perm filename APE[AP,SYS]7 blob
sn#029527 filedate 1973-03-15 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00051 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00005 00002 Definitions.
C00008 00003 More definitions.
C00013 00004 Storage allocations for statistics keeping.
C00017 00005 Storage allocations.
C00023 00006 Initialization.
C00026 00007 Initialization.
C00030 00008 Initialization.
C00032 00009 Start of main loop: asking for keywords. (RESET,RSTART,APE1)
C00034 00010 Check for various kinds of keyword expressions.
C00036 00011 Set up main story list and report nbr of stories found.
C00040 00012 Read in story selection line.
C00043 00013 Process rest of selection line.
C00046 00014 Read in story selection numbers and build up sublist of selected stories.
C00048 00015 Build up a list of the stories selected.
C00050 00016 Finish building up story sublist.
C00055 00017 LOOKUP output file to see if it already exists, then ENTER it.
C00058 00018 Read in the stories found: TYPEM
C00060 00019 Allow choosing stories. TYP7 TYP14 TYP10
C00063 00020 Put story into output file. TYP9 TYPE1
C00066 00021 Get next story in list. TYP18 GETNXT DIR8
C00069 00022 TERM MINUS PLUS FACTOR PRIMAR INTRPT CINT ESCI REENT
C00073 00023 GETWD
C00076 00024 FOUND FINWD
C00078 00025 NONE NOTFND NOMULT ASKSRC
C00081 00026 READWD
C00084 00027 READ READY GETCH
C00087 00028 GETAVL NUNAVL GTORIG
C00090 00029 ADORIG RETLST
C00093 00030 SETUPI SETUP NEXT1 NEXT2
C00095 00031 SDIFF
C00096 00032 UNION
C00097 00033 INTER
C00098 00034 COPY1 COPY2 FINISH
C00100 00035 LATEST SEQNBR
C00104 00036 GETSTY INNBR RDNBR PTZERO PRNTNO NXTDG PTREST
C00106 00037 PUTDAT CLEARU
C00108 00038 GETDAT PTIME
C00110 00039 PRINTU
C00112 00040 ZEROUS
C00113 00041 SAVPPN
C00115 00042 READIT
C00119 00043 SEARCH
C00123 00044 LOOK
C00129 00045 SHRINK UUCODE
C00131 00046 TELLKY TELLSL TELLSC
C00141 00047 NOTE
C00147 00048 NOTEDP
C00154 00049 TYKEYS
C00156 00050 READFL RFAUTO RFCON
C00163 00051 RFERR1-5 RFNAME
C00165 ENDMK
C⊗;
;Definitions.
TITLE APE
EXTERN SPOOLM,JOBREN,JOBAPR,JOBFF,JOBSA
;ACCUMULATOR ASSIGNMENTS
F←←0 ;AC0 contains flags in the left half and "@" in the right half
A←1 ;temporary AC
SORPTR←2 ;pointer into list of keywords (SORDID)
TXTPTR←3 ;pointer into block for storage of characters of keywords
D←3 ;temporary AC
B←4 ;temporary AC
CNT←4 ;counter
CHAR←6 ;current tty input character
C←7 ;temporary AC
DICTWD←10 ;pointer to current DICT entry
PART1←11 ;first 5 chars of keyword
PART2←12 ;next 5 chars of keyword
PART3←13 ;next 5 chars of keyword
PART4←14 ;next 5 chars of keyword
X←11 ;pointer into the INDEX file
DISPL←12 ;displacement of current story in NEWS from record boundary
SIZE←14 ;size of the current news story
LIST1←11 ;first operand (list of stories) in a set operation
LIST2←12 ;second operand (list of stories) in a set operation
LIST3←13 ;resultant list of stories in a set operation
X1←14 ;index of current story in first list
X2←15 ;index of current story in second list
FIRST←16 ;pointer to first part of keyword in WORDS (points to prev word)
STYPTR←16
P←17 ;push down list pointer
LF←←12 CR←←15 FF←←14 ALT←←175 TAB←←11
SPECS←←4 ;the next 7 lines must be duplicated in most AP programs
XSIZE←←3
MAXNBR←←=500
XLEN←MAXNBR*XSIZE+SPECS
WLEN←←6400
LLEN←←10000
DLEN←←6000 ;last line that must be duplicated
SLSTLN←←=750 ;length of the story list array (STYLST)
SLEN←←=15 ;length of the SORDID array
PDLEN←←=100 ;length of the pdl
STLEN←←2200 ;length of the block for holding stories in core
DEFINE UNDUNX {INDEX} ;first word in INDEX file
DEFINE NEWX {INDEX+1} ;second word
DEFINE OLDX {INDEX+2} ;third word
;More definitions.
;LEFT HALF FLAGS
DONT ←← 1 ; 0 if the stories should be typed out, 1 if they should not be
SPOOL ←← 2 ; 1 if output file should be spooled
SAVFIL←← 4 ; 1 if the output file should be saved
OP1FLG←← 10 ;bits indicating what kind of lists the operands are in a set
OP2FLG←← 20 ; operation. 1 means ptr into STYLST, 0 means ptr into LINKS.
XTND ←← OP1FLG ; 1 if the user wants output file added to (extended) with stories
REPL ←← OP2FLG ; 1 if the user wants output file to replace any file of same name
MINUS1←← 40 ; 1 if the 1st story number was preceeded by a minus sign
MINUS2←← 100 ; 1 if the 2nd story number was preceeded by a minus sign
PAIR ←← 200 ; 1 if two story selection numbers were typed in
ORDER ←← 400 ; 1 if the stories are to come out in reversed order
FEW ←← 2000 ; 1 if the user wants only the first few lines of each story
CHOOSE←← 4000 ; 1 if the user wants to choose if he wants to read rest of story
LSTFEW←← 10000 ; 1 if the user wants only the last few lines of each story
SEL ←← 20000 ; 1 if the user has already made a story selection from current list
SELNUN←← 40000 ; 1 if the user wants has selected none of the stories
KEYS ←← 100000 ; 1 if the user wants the keywords for each story typed out
DELB ←← 200000 ; 1 if the users is deleting notif requests in addition to displaying them
NOTIFY←← 400000 ; 1 if the user wants to be notified when a story matches his expr
TYPOUT← DONT!SPOOL!SAVFIL!FEW!LSTFEW!CHOOSE
;RIGHT HALF FLAGS (CANT USE LOW ORDER 7 BITS!)
GOD ←← 400000 ; 1 if the user is AP,SYS
TMPB ←← 200000 ; temporary flag
PPNDUN←← 100000 ; 1 if the user's ppn has been written in the USERS file
INFILE←← 40000 ; 1 if there is a command file open
CON ←← 20000 ; 1 if there is a command file open and the last expr ended with ","
AUTOCN←← 10000 ; 1 if keyword exprs should automatically be taken from cmd file
AUTOSC←← 4000 ; 1 if unrecognized keywords should automatically be searched for
TYPEFL←← 2000 ; 1 if stuff read from command file should be typed out
FROMFL←← 1000 ; 1 if last keyword expression was read from a command file
TMPB2 ←← 400 ; temporary flag
TMPB3 ←← 200 ; temp flag
;UNUSABLE←← 177
LOC 41
JSR UUCODE
LOC
OPDEF UERR1 [001000,,];minor error. type out message and jump to APE1
OPDEF UERR2 [002000,,];moderate error. type out message and jump to RSTART
OPDEF UERR3 [003000,,];big error. type out message and jump to RESET
OPDEF UBIGERR [004000,,];horrendous error. type out message and exit
DEFINE MEDERR(MSG) <UERR2 [ASCIZ\MSG\]>
DEFINE LGEERR(MSG) <UERR3 [ASCIZ\MSG\]>
DEFINE ECHOFF {PTYUUO 16,[0↔3]} ;PTJOBX--this turns off echoing of type-in
DEFINE ECHON {PTYUUO 16,[0↔4]} ;this turns it back on
;Storage allocations for statistics keeping.
DEFINE NAMES {
XXX URAPE ,TIMES "R APE" TYPED.....................
XXX UEXPR ,NORMAL EXPRESSIONS......................
XXX UNULL ,NULL EXPRESSIONS..................(CR)..
XXX USTAR ,CONTINUED EXPRESSIONS..............(*)..
XXX UPLUS ,CONTINUED EXPRESSIONS..............(+)..
XXX UMINUS,CONTINUED EXPRESSIONS..............(-)..
XXX UCONLF,EXPRESSIONS CONTINUED.............(LF)..
XXX UNOTIF,NOTIFICATION REQUESTS..........($expr)..
XXX UNDSPY,NOTIFICATION REQUESTS DISPLAYED....($)..
XXX UNSTOP,NOTIFICATION REQUESTS DELETED.....($$)..
XXX UATFL ,COMMAND FILES REFERENCED...........(@)..
XXX UFLXP,{COMMAND FILE EXPRESSIONS USED......(;)..}
XXX UFLSL,{COMMAND FILE SELECTION LINES.......(,)..}
XXX UTYP ,WHOLE STORIES TYPED OUT.................
XXX UFEW ,FIRST FEW LINES TYPED OUT..........(F)..
XXX UCHSF ,STORIES CHOSEN FROM................(C)..
XXX UCHS ,STORIES CHOSEN..........................
XXX ULST ,LAST FEW LINES TYPED OUT...........(L)..
XXX USPL ,STORIES SPOOLED....................(S)..
XXX UFIL ,STORIES SAVED IN FILES.......(filenm←)..
XXX UKEYS ,TIMES KEYWORDS TYPED OUT...........(W)..
XXX UUNREC,UNRECOGNIZED KEYWORDS (NO SEARCH).......
XXX USCH ,NUMBER OF SEARCHES DONE.................
}
DEFINE XXX(A,B) <
A: 0
>
LOCDAT: BLOCK 3 ;0)DSKTIM. 1)CPUTIM. 2)SRCTIM.
NAMES
0 ;extra word because of dump mode bug (losing 4 bits)
ULEN←←.-LOCDAT
TOTDAT: BLOCK ULEN
CPUTIM←←1
SRCTIM←←2
DEFINE XXX(A,B) <
[ASCIZ \B\]
>
MSGDAT←.-3
NAMES ;block of ptrs to ASCIZ strings for data in USE.DAT
USEF: SIXBIT /USE2/
SIXBIT /DAT/
BLOCK 2
UCMD: IOWD ULEN,TOTDAT
0
MONTHS: FOR MON IN (Jan,Feb,Mar,Apr,May,June,July,Aug,Sept,Oct,Nov,Dec)
< ASCIZ \MON\
>
;USERS file contains a list of programmer names of people who have used APE
USERSF: SIXBIT /USERS/
BLOCK 3
PCMD: IOWD 1,USERS
0
;USERS: ;the USERS block is common with the STORY block
USRPPN: 0
;Storage allocations.
COMMENT ⊗ I/O CHANNELS USED
0:DICT
1:LINKS
2:INDEX
3:WORDS
4:NEWS
5:output file for news
7:interlock file: NOTIF.TMP
10:input of NOTIF for displaying/stopping requests
11:NOTIF.ADD--RA mode (unimplemented)
12:input command file
13:tty (output from message file)
14:USERS
15:USE.DAT (input)
16:USE.DAT (output)
17:APMESS (message file) end of comment ⊗
NEWSF: SIXBIT /NEWS/
BLOCK 3
INDEXF: SIXBIT /INDEX/
BLOCK 3
LINKSF: SIXBIT /LINKS/
BLOCK 3
DICTF: SIXBIT /DICT/
BLOCK 3
WORDSF: SIXBIT /WORDS/
BLOCK 3
MESSF: SIXBIT /APMESS/
BLOCK 3
FILE: 0 ;ENTER block for file to which some news stories are
SIXBIT /AP/ ; to be outputted. Always given the extension .AP
BLOCK 2
NOTIFF: SIXBIT /NOTIF/
BLOCK 3
USERS: ;USERS and TMPBUF blocks are the same (common) to save space
TMPBUF: BLOCK 230
STORY: BLOCK STLEN ;block for holding text of a story in core
RQBUF←STORY+200
INDEX: BLOCK XLEN ;block for holding entire INDEX file
LINKS: BLOCK LLEN ;block for holding entire LINKS file
DICT: BLOCK DLEN ;block for holding entire DICT file
WORDS: BLOCK WLEN ;block for holding entire WORDS file
SORDID: BLOCK SLEN ;block of headers for story lists
PDLIST: BLOCK PDLEN ;area for push down list
STYLST: BLOCK SLSTLN ;block for pointers to the stories found
POLLEN←←40
POLISH: BLOCK POLLEN ;right polish for keyw expr--used with auto notif
MBUF: BLOCK 3 ;header for buffer for message file and for notif files
TBUF: BLOCK 3 ;header for buffer for TTY output from message file
DIGITS: BLOCK 4
CMD: IOWD 1,STORY
0
XCMD: IOWD XLEN,INDEX
0
LCMD: IOWD LLEN,LINKS
0
DCMD: IOWD DLEN,DICT
0
WCMD: IOWD WLEN,WORDS
0
FCMD: IOWD 1,STORY ;dump mode command for writing out selected stories
0 ; on a file
NCMD: IOWD 1,RQBUF
0
DSK17: 17 ;OPEN block for initing the dsk in mode 17
SIXBIT /DSK/
0
TOTAL: 0 ;count of the total number of stories found
FLBPTR: 0 ;byte ptr for storing sixbit filename in FILE
PPN: SIXBIT / APSYS/ ;ppn for all the AP system files
AVSLST: 0 ;ptr to first element in list of available STYLST slots
HEAD1: 0 ;ptr to first element in first story list in set operation
HEAD2: 0 ;ptr to first element in second story list in set operation
NFOUND: 0 ;total number of stories found in current story list
FSTNBR: 0 ;relative number of selected beginning story
SCDNBR: 0 ;relative number of selected ending story
HEADER: 0 ;header for the sublist of stories selected
SAVNBR: 0 ;place for saving in ASCII the nbr of stories found
NBRGON: 0 ;place for counting nbr of stories that have disappeared
LINEBP: 0 ;byte ptr into a command line typed in
BRCHAR: 0 ;char causing activation at end of typed in line
KSTART: 0 ;byte ptr to start of current keyword in keyword expr
POLPTR: 0
SMINUS: -1,,2
SPLUS: -1,,1
SSTAR: -1,,0
CRLF: ASCIZ/
/
CRLFS: ASCIZ/
/
RAPED: -1 ;counter of number of times user started APE
SEQBEG: 0 ;starting sequence number of group
SEQEND: 0 ;ending sequence number of group
STARS: ASCIZ /************************************************************
/
STARLN←←.-STARS
;Initialization.
APE: MOVE P,[IOWD PDLEN,PDLIST]
PUSHJ P,CLEARU
SETZ A,
CALLI A,27 ;RUNTIM
MOVEM A,LOCDAT+CPUTIM ;save run time at start up of ape
CALLI 0 ;RESET world
MOVEI F,"@" ;clear all flags and put "@" byte into AC
MAXT←←=45
MOVEI B,MAXT ;max length of time we try to lookup DICT
OPNDCT: OPEN 0,DSK17 ;DICT file
UBIGERR 4 ; ;OPEN FAILED ON DSK
MOVE A,PPN
MOVEM A,DICTF+3
LOOKUP 0,DICTF
JRST [RELEAS 0,
CAIL B,MAXT
OUTSTR [ASCIZ /One moment please.../]
MOVEI A,1
CALLI A,31 ;SLEEP a sec
SOJGE B,OPNDCT
UBIGERR 10] ; ;could not LOOKUP DICT for MAXT secs
HLRE A,DICTF+3 ;get size of DICT
CAMGE A,[-DLEN]
UBIGERR 14 ; ;DICT IS TOO BIG TO FIT INTO ITS ARRAY
MOVNM A,DICLEN# ;save size of dictionary
HRLM A,DCMD ;put size into dump mode command for DICT
IN 0,DCMD
JRST .+2
UBIGERR 20 ; ;IN UUO FAILED TO READ IN DICT
OPEN 1,DSK17 ;LINKS file
UBIGERR 24 ; ;OPEN FAILED ON DSK
MOVE A,PPN
MOVEM A,LINKSF+3
LOOKUP 1,LINKSF
UBIGERR 30 ; ;LOOKUP FAILED ON LINKS
IN 1,LCMD
JRST .+2
UBIGERR 34 ; ;IN UUO FAILED TO READ IN LINKS
RELEAS 1,
OPEN 2,DSK17 ;INDEX file
UBIGERR 40 ; ;OPEN FAILED ON DSK
MOVE A,PPN
MOVEM A,INDEXF+3
LOOKUP 2,INDEXF
UBIGERR 44 ; ;LOOKUP FAILED ON INDEX
IN 2,XCMD
JRST .+2
UBIGERR 50 ; ;IN UUO FAILED TO READ IN INDEX
RELEAS 2,
;Initialization.
OPEN 3,DSK17 ;WORDS file
UBIGERR 54 ; ;OPEN FAILED ON DSK
MOVE A,PPN
MOVEM A,WORDSF+3
LOOKUP 3,WORDSF
UBIGERR 60 ; ;LOOKUP FAILED ON WORDS
IN 3,WCMD
JRST .+2
UBIGERR 64 ; ;IN UUO FAILED TO READ IN WORDS
RELEAS 3,
RELEAS 0, ;keep the DICT file open until all files have been read in
INIT 17,10 ;type out the file APMESS if it exists
SIXBIT /DSK/
MBUF
UBIGERR 70 ; ;CANT INIT THE DSK
MOVE A,PPN
MOVEM A,MESSF+3
LOOKUP 17,MESSF ;is there a message file to be typed out?
JRST NOMESS ;no
OUTSTR CRLF
INIT 13,10
SIXBIT /TTY/
XWD TBUF,0
UBIGERR 74 ; ;CANT INIT THE TTY
UOUTBF 13,[2↔201]
PUSHJ P,GMSWD ;get first word of file
CAME A,[ASCII/COMME/];is it a TV file?
JRST SOSMES ;no
PUSHJ P,PMSWD
PUSHJ P,GMSWD
CAME A,[ASCII/NT ⊗ /]
JRST SOSMES ;not TV file
GETSTS 13,B
TRO B,20 ;INHIBIT SYSTEM WORD COUNT
SETSTS 13,(B)
FINDFF: PUSHJ P,GMSRC
LDB CHAR,[POINT 7,A,6];get first char of record
CAIE CHAR,FF ;FF marks end of TV directory page
JRST FINDFF
TLZ A,774000 ;zero out the FF
MOVEM A,@MBUF+1
NXREC: HRLZ B,MBUF
HRR B,TBUF
AOBJN B,.+1
MOVEI C,(B)
BLT B,200(C) ;move from DSK buffer to TTY buffer
HRRZS (C) ;zero out left half of word count word
OUTPUT 13, ;write out TTY buffer
PUSHJ P,GMSRC ;get next record of file
JRST NXREC
SOSMES: TRNN A,1 ;is this word an SOS line number?
JRST SOS1 ;no
PUSHJ P,GMSWD ;yes. ignore it and get next word from file
TLZ A,774000 ;zero out the tab following the line number
SOS1: PUSHJ P,PMSWD ;write out this word
PUSHJ P,GMSWD ;get next word from file
JRST SOSMES
PMSWD: SOSG TBUF+2 ;put word into TTY buffer
OUTPUT 13,
IDPB A,TBUF+1
POPJ P,
GMSWD: SOSG MBUF+2
GMSRC: IN 17, ;get next record (buffer) from message file
JRST [ILDB A,MBUF+1 ;get word from buffer
POPJ P,]
SUB P,[1,,1]
RELEAS 13, ;TTY
NOMESS: RELEAS 17, ;message file
PUSHJ P,SHRINK ;release any extra core accumulated
;Initialization.
MOVEI A,INTRPT
MOVEM A,JOBAPR ;set up address of interrupt module
HRLZI A,4 ;enable for interrupts on [ESC] I
CALLI A,400025 ;INTENB
MOVEI A,REENT
MOVEM A,JOBREN ;set up reentry address
AOSN RAPED ;add one to count of number of restarts
AOS URAPE ;bump "r ape" count first time only
SETZ A,
CALLI A,24 ;GETPPN
MOVEM A,USRPPN
HRRZ B,A
CAME A,PPN
CAIN B,' ME'
TROA F,GOD
NOSPEC: PUSHJ P,SAVPPN
;Start of main loop: asking for keywords. (RESET,RSTART,APE1)
OUTSTR [ASCIZ /
Type ? and RETURN at any time for help.
/]
; $
RESET: MOVE A,[XWD -SLSTLN+2,STYLST];clear the current story list and
HRRZM A,AVSLST ; return all words of STYLST array
ADDI A,1 ; to the available space list
HRRZM A,-1(A)
AOBJN A,.-1
SETZM -1(A) ;put null ptr at end of available list
SETZM SORDID ;clear ptr to current story list
SETZM HEADER ;clear header to current story sublist
RSTART: MOVE P,[IOWD PDLEN,PDLIST] ;reset the pdl pointer (eg, after errors)
APE1: INSKIP ;reset any printout stop (↑O)
JFCL
SETZ SORPTR, ;point to header of current story list
SETOM POLPTR ;set length of polish expression to zero
TDZ F,[TYPOUT!NOTIFY,,AUTOSC!FROMFL];clear some flags
OUTSTR [ASCIZ /
KEYWORD EXPRESSION: /] ;ask for keywords expression
TRNE F,AUTOCN
TRNN F,INFILE
JRST KEY5
PUSHJ P,RFAUTO
JRST APE1
JRST KEY6
KEY5: TRNN F,GOD!PPNDUN
PUSHJ P,SAVPPN ;put PPN in USERS file
TRNN F,GOD
PUSHJ P,PUTDAT ;record usage data
PUSHJ P,READ ;read in keyword expression
KEY1: MOVEI CHAR,LF
CAME CHAR,BRCHAR
JRST KEY2
OUTCHR [":"]
AOS UCONLF
MOVEI CHAR," "
DPB CHAR,B
PUSHJ P,READ1
JRST KEY1
;Check for various kinds of keyword expressions.
KEY2: PUSHJ P,GETCH ;get first char of expr into CHAR
CAIN CHAR,"?"
JRST TELLKY ;wants some help!!
CAIE CHAR,"@"
JRST KEY4
PUSHJ P,READFL
JRST APE1
KEY6: PUSHJ P,GETCH
TRNN F,INFILE
JUMPE CHAR,APE1
TRO F,FROMFL ;indicate expression read from command file
AOS UFLXP
KEY4: JUMPN CHAR,KEY3 ;is keyword expression null?
AOS UNULL ;yes
JRST APE2 ;CR. use current story list
KEY3: CAIN CHAR,"+" ;does expression start with "+"?
JRST [PUSHJ P,PLUS ;yes. perform union with current story list
AOS UPLUS
JRST CHECK]
CAIN CHAR,"-" ;does expression start with "-"?
JRST [PUSHJ P,MINUS ;yes. perform set difference from current story list
AOS UMINUS
JRST CHECK]
CAIN CHAR,"*" ;does expression start with "*"?
JRST [PUSHJ P,INTER ;yes. perform intersection with current story list
PUSHJ P,TERM2
AOS USTAR
JRST CHECK]
CAIN CHAR,"$"
PUSHJ P,[TLO F,NOTIFY ;wants to be notified
JRST GETCH]
JUMPE CHAR,NOTEDP ;just $ means display notification requests
CAIN CHAR,"$" ;two $'s means display and allow deletion
JRST NOTEDL
PUSHJ P,TERM ;read in a whole keyword expression
AOS UEXPR
;Set up main story list and report nbr of stories found.
CHECK: JUMPE CHAR,.+2 ;zero means have processed whole expression
MEDERR (SYNTAX ERROR) ; ;there were some chars after the TERM
HRRE LIST1,SORDID(SORPTR) ;get ptr to first element in final story list
JUMPGE LIST1,APE2 ;is story list a list in LINKS?
MOVN LIST1,LIST1 ;yes. copy it into STYLST
HRRZ X1,LINKS+1(LIST1) ; get index ptr to first story
MOVEI LIST3,SORDID(SORPTR) ; set up in LIST3 a ptr to prev list element
TLZ F,OP1FLG ; indicate operand 1 is a list in LINKS
SETZM HEAD1 ; indicate no lists to be returned to
SETZM HEAD2 ; available STYLST storage
PUSHJ P,COPY1 ; actually copy the list into STYLST
APE2:
JUMPE SORPTR,APE8 ;is old current story list being used?
SKIPE A,SORDID ;no. is it null?
PUSHJ P,RETLST ;no. return it to free storage
APE8: HRRZ LIST3,SORDID(SORPTR) ;get ptr to first element in story list
HRRZM LIST3,SORDID ;store it in header to current story list
SETZ CNT, ;initialize the count of stories to zero
JUMPE LIST3,NOMORE ;check for null list
APE3: ADDI CNT,1 ;add 1 to count of stories
HRRZ LIST3,(LIST3) ;get ptr to next element in story list
JUMPN LIST3,APE3 ;check if at end of list
NOMORE: MOVEM CNT,NFOUND ;save the number of stories found
TLNE F,NOTIFY ;notification requested?
PUSHJ P,NOTE ;yes. write request on file
SKIPG PART1,NFOUND
JRST NONE ;no stories found
MOVE B,[POINT 7,DIGITS]
SETZM DIGITS
PUSHJ P,NXTDG
MOVE A,DIGITS
MOVEM A,SAVNBR ;save ascii of cnt in case of error
JRST ASK
CONERR: OUTSTR [ASCIZ/CONTRADICTORY SELECTIONS/]
ASKERR: PUSHJ P,PTREST
ASKER1: TRZ F,FROMFL!AUTOCN ;accept only one selection line from file
ASK: OUTSTR SAVNBR ;type out the number
OUTSTR [ASCIZ / news item(s) found. Selection: /]
TLZ F,TYPOUT!ORDER!MINUS1!MINUS2!PAIR!SEL!SELNUN!KEYS;clear flags
MOVE A,NFOUND
MOVEM A,FSTNBR ;pretend user has choosen all stories
TRC F,INFILE!CON!FROMFL
TRCE F,INFILE!CON!FROMFL
JRST ASK2
PUSHJ P,RFCON
JRST ASKER1
AOS UFLSL
JRST ASK3
;Read in story selection line.
ASK2: PUSHJ P,READ ;read in whole line
ASK3: ILDB CHAR,LINEBP ;see if there is a file name specified?
CAIN CHAR,"?"
JRST TELLSL
CAIE CHAR,"←"
JUMPN CHAR,ASK3
MOVE A,[POINT 7,TMPBUF]
MOVEM A,LINEBP
CAIE CHAR,"←" ;is there a file name specified?
JRST ASK1 ;no
MOVE A,[POINT 6,FILE] ;yes. put it into LOOKUP/ENTER block
MOVEI B,6
SETZM FILE
TLZ F,XTND,REPL
PUSHJ P,GETCH
GFL1: CAIN CHAR,"←"
JRST GFL9
CAIN CHAR,"."
JRST GFL8
CAIN CHAR,"["
JRST GFL7
CAIN CHAR,"/"
JRST FLSWCH
CAIG CHAR,40
JRST GFL6
SOJL B,GFL5
TRZ CHAR,40 ;convert file name char to sixbit
TRZE CHAR,100
TRO CHAR,40
IDPB CHAR,A ;save file name char
ILDB CHAR,LINEBP
JRST GFL1
GFL5: OUTSTR [ASCIZ/FILE NAME TOO LONG/]
JRST ASKERR
GFL6: OUTSTR [ASCIZ/ILLEGAL CHAR IN FILE NAME/]
JRST ASKERR
GFL7: OUTSTR [ASCIZ/PPN NOT ALLOWED/]
JRST ASKERR
GFL8: OUTSTR [ASCIZ/FILE NAME EXTENSION NOT ALLOWED/]
JRST ASKERR
FLSWCH: PUSHJ P,GETCH ;read in file switch
CAIE CHAR,"Q"
CAIN CHAR,"q"
JRST SETRPL ;wants to replace old file of same name
CAIE CHAR,"X"
CAIN CHAR,"x"
JRST SETXTD ;wants to extend old file
JRST SWERR
SETRPL: TLOA F,REPL
SETXTD: TLO F,XTND
PUSHJ P,GETCH
CAIN CHAR,"←" ;switch must be last part of file spec
JRST GFL9
SWERR: OUTSTR [ASCIZ/ILLEGAL FILE SWITCH/]
JRST ASKERR
GFL9: SKIPE FILE
JRST GFL10
OUTSTR [ASCIZ/NULL FILE NAME ILLEGAL/]
JRST ASKERR
GFL10: TLO F,SAVFIL
;Process rest of selection line.
CONTRA← DONT!FEW!CHOOSE!LSTFEW!SELNUN!SPOOL!SAVFIL;more or less contradictory flags
ASK1: PUSHJ P,GETCH ;get next char of line
WHICH0: JUMPE CHAR,CLUNK ;zero means have found end of selection line
CAIE CHAR,"F"
CAIN CHAR,"f"
JRST [TLO F,FEW ;wants only the First few lines of each story
TLNE F,CONTRA-(FEW!LSTFEW)
JRST CONERR
JRST ASK1]
CAIE CHAR,"C"
CAIN CHAR,"c"
JRST [TLO F,CHOOSE ;wants to Choose which stories he reads
TLNE F,CONTRA-(CHOOSE!SPOOL!SAVFIL)
JRST CONERR
JRST ASK1]
CAIE CHAR,"L"
CAIN CHAR,"l"
JRST [TLO F,LSTFEW ;wants only the Last few lines of each story
TLNE F,CONTRA-(LSTFEW!FEW)
JRST CONERR
JRST ASK1]
CAIE CHAR,"N"
CAIN CHAR,"n"
JRST [TLO F,SELNUN ;doesn't want to see any of the stories
TLNE F,(SEL!CONTRA)-(SELNUN!DONT)
JRST CONERR
JRST ASK1]
CAIE CHAR,"S"
CAIN CHAR,"s"
JRST [TLO F,SPOOL ;wants stories selected to be spooled
TLNE F,CONTRA-(SPOOL!CHOOSE!DONT!SAVFIL)
JRST CONERR
JRST ASK1]
CAIE CHAR,"W"
CAIN CHAR,"w"
JRST [TLO F,KEYS ;wants list of keywords for each story
JRST ASK1]
CAIE CHAR,"D"
CAIN CHAR,"d"
JRST [TLO F,DONT ;doesn't want stories typed out
TLNE F,CONTRA-(DONT!SPOOL!SAVFIL!SELNUN)
JRST CONERR
JRST ASK1]
CAIE CHAR,"K"
CAIN CHAR,"k"
JRST [TRZ F,AUTOCN ;wants to discontinue automatic reading
JRST ASK1] ; from command file
CAIN CHAR,"?"
JRST TELLSL ;wants some help!
;Read in story selection numbers and build up sublist of selected stories.
WHICH2: CAIE CHAR,"=" ;does he want the order of the stories reversed?
JRST WHICH1 ;no
TLC F,ORDER ;yes
JRST ASK1
WHICH1: TLOE F,SEL ;has he already made a story selection?
JRST SELERR ;yes. some unknown stuff in selection line
CAIE CHAR,"-"
JRST WHICH3
TLO F,MINUS1 ;set flag to indicate that 1st story nbr was negative
PUSHJ P,GETCH
WHICH3: PUSHJ P,GETSTY
JUMPE CNT,SELERR
CAMLE CNT,NFOUND ;has a nonexistent story been selected?
JRST NONEXS
MOVEM CNT,FSTNBR
CAIE CHAR,":"
JRST WHICH0
TLO F,PAIR ;set flag to indicate that a pair of nbrs were typed in
PUSHJ P,GETCH
CAIE CHAR,"-"
JRST WHICH7
TLO F,MINUS2 ;set flag to indicate that 2nd story nbr was negative
PUSHJ P,GETCH
WHICH7: PUSHJ P,GETSTY
JUMPE CNT,SELERR
CAMLE CNT,NFOUND
JRST NONEXS
MOVEM CNT,SCDNBR
JRST WHICH0
NONEXS: OUTSTR [ASCIZ /STORY NUMBER TOO BIG: /]
MOVE PART1,CNT
PUSHJ P,PRNTNO
OUTSTR CRLF
JRST ASKER1
SELERR: OUTSTR [ASCIZ/SELECTION ERROR/]
JRST ASKERR
;Build up a list of the stories selected.
CLUNK: TLNE F,SELNUN ;has he selected none of the stories?
JRST APE1 ;yup. give him what he wants
TLNE F,DONT
TLNE F,SAVFIL!SPOOL!KEYS
JRST .+2
JRST APE1 ;dont type, file, or spool!!
TLNE F,PAIR ;were a pair of story numbers typed in?
JRST HAVEPR ;yes
TLNE F,MINUS1 ;no. did the story number have a minus sign?
JRST GETOLD ;yes
MOVEI A,1 ;no. select the most recent FSTNBR stories
EXCH A,FSTNBR
MOVEM A,SCDNBR ;end with story number FSTNBR
JRST BUILD
GETOLD: MOVE A,NFOUND
MOVEM A,SCDNBR ;end with last story
SUB A,FSTNBR ;calculate the number of the FSTNBR oldest story
ADDI A,1
MOVEM A,FSTNBR ;store number of starting story
JRST BUILD
HAVEPR: TLNN F,MINUS1 ;did the first story number have a minus sign?
JRST CHK2ND ;no. see if the 2nd story did.
MOVE A,NFOUND ;yes
SUB A,FSTNBR ;calculate the number of the FSTNBR oldest story
ADDI A,1
MOVEM A,FSTNBR ;store number of starting story
CHK2ND: TLNN F,MINUS2 ;did the second story number have a minus sign?
JRST BUILD ;no
MOVE A,NFOUND ;yes
SUB A,SCDNBR ;calculate the number of the SCDNBR oldest story
ADDI A,1
MOVEM A,SCDNBR ;store number of ending story
;Finish building up story sublist.
BUILD: SKIPE A,HEADER ;is there a non-null sublist sitting around?
PUSHJ P,RETLST ;yes. return it to free storage
SETZM HEADER
GRONK: MOVE A,FSTNBR ;load numbers of beginning and ending stories and
MOVE B,SCDNBR ; build up sublist of those stories
CAMG A,B ;are oldest stories to come first?
JRST BUILD1 ;no
EXCH A,B ;put number of lowest numbered story into A
TLC F,ORDER ;set flag indicating the list built up should be in rev order
BUILD1: SUBI B,-1(A) ;put number of stories to be collected into B
HRRZ LIST1,SORDID(SORPTR);get ptr to first element of whole list
BUILD2: MOVE LIST1,(LIST1) ;get the next element of the whole list
SOJG A,BUILD2 ;have we reached the first story for the sublist?
TLNE F,ORDER ;yes. should the stories be collected in reverse order?
JRST BLDREV ;yes
MOVEI LIST3,HEADER ;get ptr to the header for the sublist
BUILD3: PUSHJ P,GETAVL ;put this story into the sublist
HLLM LIST1,(LIST3) ;put the index of this story into the sublist element
MOVE LIST1,(LIST1) ;get the next element of the whole list
SOJG B,BUILD3 ;have we collected the necessary number of stories?
HLLZS (LIST3) ;yes. put null ptr at end of sublist
HRRZ LIST3,HEADER ;load LIST3 with ptr to first element of sublist
JRST DOESHE
BLDREV: SETZ LIST3, ;make ptr to current sublist element null
REV3: SKIPN STYPTR,AVSLST ;get available word for reversed story list
JRST NUNAVL ;there are no available words for the story list!
MOVE A,(STYPTR) ;get ptr to 2nd available word and store it
MOVEM A,AVSLST ; in header of available list
HRRZM LIST3,(STYPTR) ;put ptr to prev list element in new list element
MOVE LIST3,STYPTR ;put ptr to new element into LIST3
HLLM LIST1,(LIST3) ;put the index of this story into the sublist element
MOVE LIST1,(LIST1) ;get the next element of the whole list
SOJG B,REV3 ;have we collected the necessary number of stories?
HRRZM LIST3,HEADER ;store ptr to the sublist for returning it to avail storage
DOESHE: TLNN F,SAVFIL!SPOOL ;is there to be an output file???
JRST TYPEM ;no
DIR2: TLNE F,SAVFIL ;does he want the news saved in a file?
JRST DIR5 ;yes. go lookup/enter file
MOVE A,[SIXBIT /$NEWS0/];initialize name for file to be spooled
DIR9: MOVEM A,FILE ;put file name in LOOKUP/ENTER block
MOVE B,USRPPN
MOVEM B,FILE+3 ;put file to be spooled on user's real disk area
OPEN 5,DSK17
UBIGERR 110 ; ;OPEN FAILED ON DSK
LOOKUP 5,FILE ;does file already exist?
JRST DIR6 ;no. go do an ENTER on it
RELEAS 5, ;yes. increment special name and try again
AOJA A,DIR9
;LOOKUP output file to see if it already exists, then ENTER it.
DIR5: OPEN 5,DSK17 ;see if file specified already exists.
UBIGERR 100 ; ;OPEN FAILED ON DSK
SETZM FILE+3 ;file will be on the users area
TLNN F,REPL
LOOKUP 5,FILE
JRST DIR6 ;file doesn't exist or should be replaced. ENTER it
TLNE F,XTND
JRST EXTEND
OUTSTR [ASCIZ /FILE ALREADY EXISTS!
Type Q to replace, X to extend, or just <return> for new selection line: /]
PUSHJ P,READ
PUSHJ P,GETCH
CAIE CHAR,"Q"
CAIN CHAR,"q"
JRST DIR6 ;replace specified file
CAIE CHAR,"X"
CAIN CHAR,"x"
JRST EXTEND ;extend specified file
RELEAS 5,
CAIN CHAR,"?"
FLQUES: OUTSTR [ASCIZ $
Follow the filename with /Q to have any old file of same name replaced
with a file containing the currently selected stories.
Follow the filename with /X to have any old file of same name extended
by adding the currently selected stories at the end of the old file.
$]
JRST ASKER1 ;ask for another selection line
;Enter file for saving/spooling stories.
DIR6: RELEAS 5,
OPEN 5,DSK17 ;do an ENTER on the output file for the news
UBIGERR 104 ; ;OPEN FAILED ON DSK
EXTEND: HLLZS FILE+1 ;file gets standard extension .AP
SETZM FILE+2
SETZM FILE+3 ;put file on user's disk area
MOVE B,USRPPN
TLNN F,SAVFIL ;is this file to be saved?
MOVEM B,FILE+3 ;no. put it on disk area of user's logged in ppn
ENTER 5,FILE
JRST DIR14 ;ENTER failed
UGETF 5,B ;set file ptr to end of file
JRST TYPEM ;ENTER succeeded
DIR14: RELEAS 5,
TLNN F,SAVFIL ;was the ENTER for a file only to be spooled?
AOJA A,DIR9 ;yes. increment the name of the special spooling file
OUTSTR [ASCIZ /
ENTER failed on output file!
/] ;no. tell user that the ENTER failed on the file name he gave
JRST ASKER1 ;go ask for another file name
;Read in the stories found: TYPEM
TYPEM: OUTSTR CRLFS
TLNN F,KEYS
TLNN F,DONT ;type out row of stars before first story if typing
OUTSTR STARS
SETZM AMT# ;indicate nothing in overflow buffer
SETZM NBRGON ;zero out the counter of stories gone
SETZM INTFG ;clear [ESC] I flag
NXTSTY: HLRZ X,(LIST3) ;get index of current story in story list
TLNE F,KEYS ;does he want to see keywords for this story?
PUSHJ P,TYKEYS ;yes. type them out
EXTRA: PUSHJ P,READIT ;read in the story
JRST [HRRE X,INDEX(X);story not found in NEWS
JUMPG X,EXTRA ;does story have a follow up?
AOS NBRGON ;no. count nbr of stories completely gone
JRST GETNXT] ;go on to next story
SKIPE INTFG
JRST ESCI
TLNN F,FEW ;does he want only first few lines of each story?
JRST TYP7 ;no
AOS UFEW
TLNE F,LSTFEW ;does he also want the last few lines?
JRST TYP5 ;yes
MOVE A,CRLFS ;no. type out only the first few lines
MOVEM A,=50(DISPL) ;print only first =50 words (=250 chars)
OUTSTR (DISPL) ;type out the first few lines
JRST TYP8
TYP5: MOVEI B,=80 ;type out only the first few and the last few lines
CAML B,TOTSIZ
JRST TYP4 ;small story. type out whole thing
MOVE A,CRLFS
MOVEM A,=50(DISPL)
OUTSTR (DISPL)
JRST TYP10
;Allow choosing stories. TYP7 TYP14 TYP10
TYP7: TLNN F,CHOOSE ;does he want to choose which stories get typed out?
JRST TYP14 ;no
INSKIP ;reset ↑O
JFCL
AOS UCHSF
ECHOFF ;turn off echoing for choose response
SETZ A,
EXCH A,=50(DISPL)
OUTSTR (DISPL) ;type out first part of story
SKIPE INTFG
JRST CINT
INCHWL CHAR ;see what user wants to do now
ECHON ;turn echoing back on
CLRBFI
CAIN CHAR,CR ;just <CRLF> means dont type out rest of story
JRST [OUTSTR CRLFS↔JRST TYP18]
CAIE CHAR,"I" ; I <CRLF> means give up this fruitless process
CAIN CHAR,"i"
JRST CINT
AOS UCHS
MOVEM A,=50(DISPL) ;anything else means type out rest of story
MOVEI B,=50
CAMGE B,TOTSIZ
OUTSTR =50(DISPL) ;type out remainder
JRST TYP15
TYP14: TLNN F,LSTFEW ;does he want only the last few lines of each story?
JRST TYP6 ;no
TYP10: MOVEI A,STORY-=25 ;yes. compute ptr to =25 words before end of story
SUB A,SIZE
CAMGE A,DISPL ;is this ptr in middle of story?
TYP4: MOVE A,DISPL ;no. must be a very short story. type it all out.
OUTSTR (A)
AOS ULST
JRST TYP8
TYP6: TLNE F,DONT ;does user want the story typed out?
JRST TYP15 ;no
OUTSTR (DISPL) ;type out the story
AOS UTYP
TYP15: TLNN F,SAVFIL+SPOOL ;is there an output file?
JRST TYPE1 ;no
;Put story into output file. TYP9 TYPE1
TYP9: MOVE A,AMT ;get number of words left over last time
MOVE B,TOTSIZ ;get total size of current story
ADD B,A ;amount that now needs to be output
MOVE D,B
ANDI D,177 ;amount that will be left over this time
MOVEM D,AMT ;save this nbr for next time
ANDI B,777600 ;amount that will be output now (multiple of 200)
JUMPE B,FIL6 ;any stuff going out now?
MOVN D,B ;yes
JUMPN A,FIL2 ;was there any stuff left over from before?
HRLI D,-1(DISPL) ;no. output from beginning of story
JRST FIL3
FIL2: MOVSI C,(DISPL) ;move main part of story up to end of
HRRI C,TMPBUF(A) ; left over stuff
BLT C,TMPBUF-1(B)
HRLI D,TMPBUF-1 ;output from beginning of left over stuff
FIL3: MOVSM D,FCMD
OUT 5,FCMD ;write out the story on the output file
JRST .+2
UBIGERR 114 ; ;OUT UUO FAILED TO WRITE OUT A STORY ON A FILE
ADD DISPL,B
SUB DISPL,A
SETZ A, ;stuff left over from last time is now gone
FIL6: HRLZ DISPL,DISPL ;move new left over stuff to save it for next time
HRRI DISPL,TMPBUF(A)
SKIPE C,AMT ;if no left over stuff, no use moving it
BLT DISPL,TMPBUF-1(C)
TLNE F,SAVFIL
AOS UFIL ;increment number of stories filed
TLNE F,SPOOL
AOS USPL ;increment number of stories spooled
;Get follow-up story if any, else get next story. Finish up.
TYPE1: HRRE X,INDEX(X) ;is this story linked up with a follow-up
JUMPG X,EXTRA ; story of some kind?
TLNE F,DONT ;no. is the news being typed out?
TLNE F,KEYS
JRST TYP8
OUTCHR ["@"] ;no. type out an "@" for each story writen on the file
TYP8: TLNN F,SAVFIL+SPOOL ;are the stories are being filed?
JRST TYP18 ;no
MOVE A,AMT ;yes. put a row of *'s in the file
MOVSI B,STARS
HRRI B,TMPBUF(A)
BLT B,TMPBUF+STARLN-1(A);move *'s into overflow buffer
ADDI A,STARLN
MOVEM A,AMT
;Get next story in list. TYP18 GETNXT DIR8
TYP18: INSKIP ;reset typeout flag in case user typed ↑O
JFCL
SKIPE INTFG
JRST ESCI
TLNN F,KEYS
TLNN F,DONT ;if the news is being typed out, separate stories
OUTSTR STARS ; with a row of *'s
GETNXT: HRRZ LIST3,(LIST3) ;get ptr to next element in story list
JUMPN LIST3,NXTSTY ;if not at end of list, go back and process next story
SKIPE INTFG
JRST ESCI
SKIPN PART1,NBRGON
JRST DIR8
PUSHJ P,PRNTNO
OUTSTR [ASCIZ / OF THE STORIES WENT AWAY--SORRY
/]
DIR8: TLNE F,DONT ;the stories have now been outputted
OUTSTR CRLF ; as requested
TLNN F,SPOOL+SAVFIL ;is there an output file?
JRST APE1 ;no. nothing left to do
MOVN A,AMT ;yes. finish writing out file
JUMPE A,FIL4
HRLI A,TMPBUF-1 ;set up dump mode command to output overflow buffer
MOVSM A,FCMD
OUT 5,FCMD
JRST .+2
UBIGERR 120 ; ;OUT UUO FAILED TO OUTPUT OVERFLOW BUFFER
FIL4: RELEAS 5,
TLNN F,SPOOL ;is the file to be spooled?
JRST APE1 ;no
HLLZS FILE+1 ;yes. zero the spooler flags
SETZM FILE+3 ;use user's current disk ppn
TLNE F,SAVFIL ;should the file be deleted after spooling?
JRST FIL4B ;no
MOVEI A,1 ;yes
HRRM A,FILE+1 ;set the delete flag for spooler
MOVE A,USRPPN ;the spool file to be deleted is on disk area of
MOVEM A,FILE+3 ; the user's logged in ppn
FIL4B: PUSHJ P,SPOOLM ;spool the file
JUMP FILE ;ptr to data block for spooler
JRST APE1 ;go back and get next set of keywords
;TERM MINUS PLUS FACTOR PRIMAR INTRPT CINT ESCI REENT
TERM: PUSHJ P,FACTOR ;term ::= factor { [+|-] factor }
TERM2: CAIN CHAR,"+" ; where [...] means choose one of ..., and
JRST PLUS ; where {...} means ... may occur zero or more times
CAIE CHAR,"-"
POPJ P,
MINUS: PUSHJ P,SDIFF ;take the set difference of the two factors separated by -
PUSHJ P,SAVPOL
SMINUS
JRST TERM2 ;look for more +'s or -'s
PLUS: PUSHJ P,UNION ;take the union of the two factors separated by +
PUSHJ P,SAVPOL
SPLUS
JRST TERM2 ;look for more +'s or -'s
FACTOR: PUSHJ P,PRIMAR ;factor ::= primary { * factor }
FACT2: CAIE CHAR,"*" ; note: factors are intersected from right to
POPJ P, ; left since in this case that's equivalent to left to right
PUSHJ P,INTER ;take the intersection of the primary and factor separated by *
PUSHJ P,SAVPOL
SSTAR
JRST FACT2
PRIMAR: CAIE CHAR,"(" ;primary ::= keyword | ( term )
JRST GETWD ;no "(". get a keyword.
PUSHJ P,GETCH ;found "(". get next char.
PUSHJ P,TERM ;get term following "("
CAIN CHAR,")" ;check for ")" after term
JRST GETCH ;found ")". get next char and return from PRIMAR
MEDERR (MISSING RIGHT PARENTHESIS) ; ;
INTRPT: SETOM INTFG# ;so he typed [ESC] I, did he...
SETZM STORY ;zero out any story in core to stop an outstr
MOVE A,[XWD STORY,STORY+1]
BLT A,STORY+STLEN-1
CLRBFO
CALLI 400024 ;DISMIS
CINT: ECHON ;make sure echoing is on!
ESCI: OUTSTR [ASCIZ /
↑I
/] ;user typed [ESC] I while typing out stories
REENT: CLRBFI ;would you believe reentry address?
RELEAS 4, ;let go of NEWS file!
RELEAS 5,3 ;throw away output file if open
TRZ F,AUTOCN ;disable automatic reading from command file
JRST RSTART
;GETWD
GETWD: SETZM ORIGHD
ADDI SORPTR,1 ;make new entry in SORDID for story list for this keyword
CAIL SORPTR,SLEN
MEDERR (Too many keywords)
CAIN CHAR,"." ;does this keyword specify the latest news?
JRST LATEST ;yes
CAIN CHAR,"#" ;does this "keyword" specify a certain seq nbr?
JRST SEQNBR ;yes. collect all stories with given seq nbr
MOVE A,LINEBP
MOVEM A,KSTART ;save byte ptr to current keyword
PUSHJ P,READWD
CKNULL: CAMN PART1,[NULL: ASCII /@@@@@/];is the word null (has no characters)?
MEDERR (MISSING KEYWORD) ; ;
SETZ DICTWD, ;initialize ptr to just before 1st word in dictionary
NXTDWD: ADDI DICTWD,2 ;advance DICTWD ptr to the next word in the dictionary
HLRZ FIRST,DICT(DICTWD) ;get ptr to the text of the dictionary word
MOVE A,CNT ;move length of typed-in keyword into A
;compare the typed-in keyword with the dictionary word
CAME PART1,WORDS(FIRST) ;method of comparison: compare 5 chars at a time
JRST CK1 ; until either the two words differ or
AOJGE A,FOUND ; the end of the typed-in keyword is
CAME PART2,WORDS+1(FIRST) ; reached. If the two words differ, check
JRST CK2 ; which comes first alphabetically. If the
AOJGE A,FOUND ; dictionary word comes first, go back and
CAME PART3,WORDS+2(FIRST) ; get the next dictionary word. If the
JRST CK3 ; typed-in word comes first, then it
AOJGE A,FOUND ; isn't in the dictionary.
CAMN PART4,WORDS+3(FIRST)
JRST FOUND
CK4: CAMG PART4,WORDS+3(FIRST)
JRST NOTFND ;typed-in word not in the dictionary
JRST NXTDWD ;get the next dictionary word
CK3: CAMG PART3,WORDS+2(FIRST)
JRST NOTFND
JRST NXTDWD
CK2: CAMG PART2,WORDS+1(FIRST)
JRST NOTFND
JRST NXTDWD
CK1: CAMG PART1,WORDS(FIRST)
JRST NOTFND
JRST NXTDWD
;FOUND FINWD
FOUND: PUSHJ P,GETCH1
PUSHJ P,READWD
CAMN PART1,NULL
JRST FINWD
HLRZ DICTWD,DICT+1(DICTWD)
NXBRO: JUMPE DICTWD,NOMULT ; 0 means user wants mult key, but there is none
HLRZ FIRST,DICT(DICTWD)
MOVE A,CNT
CAME PART1,WORDS(FIRST)
JRST GETBRO
AOJGE A,FOUND
CAME PART2,WORDS+1(FIRST)
JRST GETBRO
AOJGE A,FOUND
CAME PART3,WORDS+2(FIRST)
JRST GETBRO
AOJGE A,FOUND
CAMN PART4,WORDS+3(FIRST)
JRST FOUND
GETBRO: HRRZ DICTWD,DICT+2(DICTWD)
JRST NXBRO
FINWD: HRRZ A,DICT+1(DICTWD) ;get ptr to first LINKS slot for this word
CAIN A,-1
JRST NOMULT
MOVN A,A
HRRM A,SORDID(SORPTR) ; and store it negated with this keyword
PUSHJ P,SAVPOL
DICTWD
JRST GETCH1 ;skip any special chars after keyword (blanks, CR's, LF's, tabs
SAVPOL: TLNN F,NOTIFY ;is this a notif request?
JRST CPOPJ1 ;no
PUSH P,A ;yes. save a couple of ACs
PUSH P,B
AOS A,POLPTR
CAIL A,POLLEN ;have we overflowed array for polish expr?
JRST SAVPL2 ;YES. DISABLE THE REQUEST
MOVE B,@-2(P)
MOVE B,(B)
MOVEM B,POLISH(A)
SAVPL1: POP P,B ;restore the ACs and take skip return ALWAYS
POP P,A
AOS (P)
POPJ P,
SAVPL2: TLZ F,NOTIFY
OUTSTR [ASCIZ \EXPRESSION TOO LONG FOR NOTIFICATION.
\]
JRST SAVPL1
;NONE NOTFND NOMULT ASKSRC
NONE: OUTSTR [ASCIZ /NO NEWS ITEMS FOUND/] ;keywords had no associated news stories
JRST APE1
NOTFND: CAME PART1,[ASCII /FOO@@/]
JRST NOT1
PUSHJ P,PRINTU ;print out usage data
JRST RSTART
NOT1: CAMN PART1,[ASCII /BAZ@@/]
TRNN F,GOD
JRST NOMULT
PUSHJ P,PRINTU ;print out usage data
PUSHJ P,ZEROUS ; and then zero it
JRST RSTART
NOMULT: PUSHJ P,GETCH1 ;get next nonblank char
PUSHJ P,READWD ;get rest of mult word keyword, if any
CAME PART1,NULL ;if null, no more mult sub words
JRST NOMULT
AOS A,POLPTR ;move text of unrec keyw into a buffer so
CAIL A,POLLEN ; that we can outstr it and search for it
HALT . ; ;
ADDI A,POLISH ;make byte pointer into the POLISH block
HRLI A,700
MOVEM A,TMPBP#
MOVEM A,FSTBP# ;save byte pointer to beginning of string
MOVE B,KSTART ;get byte pointer to beginning of keyword
LDB A,B ;get first char of keyword
JRST .+2
ILDB A,B ;get next char of keyword
IDPB A,TMPBP ; and save it in string in POLISH block
CAME B,LINEBP ;got last char of keyword?
JRST .-3 ;no. get another
SETZ A, ;yes. put a null byte after string
DPB A,TMPBP
ASKSRC: OUTSTR [ASCIZ /Unrecognized keyword: /]
HRRZ A,FSTBP
OUTSTR 1(A) ;type out the unrec keyword
TROE F,AUTOSC ;should we search without asking?
JRST LOOK0 ;yes
OUTSTR [ASCIZ /. Search? /] ;no. ask if we should search
PUSHJ P,READY ;read in the answer
JRST LOOK ;"Y"
JRST TELLSC ;"?". wants some help.
NOM1: AOS UUNREC ;any other char means no search
JRST RSTART ;give up on this keyw expr
;READWD
READWD: SETZ PART1,
SETZ PART2,
SETZ PART3,
SETZ PART4,
MOVEI CNT,=20 ;limit the number of chars in keyword to 20
MOVE TXTPTR,[POINT 7,PART1] ;initialize byte ptr to deposit chars in ACs PART1-4
NXTCHR: CAIL CHAR,"a" ;is current char a small letter?(less than"a"?)
CAILE CHAR,"z" ;maybe. Is it less than than "z"?
JRST NOTSML ;not a small letter
TRZ CHAR,40 ;was a small letter. turn off 40 bit making it a cap letter
JRST GOTLTR
NOTSML: CAIL CHAR,"0" ;is this char eligible to be in a keyword?
CAILE CHAR,"Z"
JRST RWD1 ;no. must be end of keyword
CAILE CHAR,"9" ;maybe. does it come between "9" and "A"?
CAIL CHAR,"A"
JRST GOTLTR ;no. must be a letter or a digit
JRST RWD1 ;yes. end of keyword
GOTLTR: SOJL CNT,.+2 ;it is a letter. has keyword already got 20 chars in it?
IDPB CHAR,TXTPTR ;no. put current char in TEXT
ILDB CHAR,LINEBP ;get the next character
JRST NXTCHR
RWD1: JUMPG CNT,DEP100
HRREI CNT,-4 ;put negated number of ACs holding keyword into CNT
POPJ P,
DEP100: IDPB F,TXTPTR ;deposit an "@" at end of keyword in PARTs
SUBI CNT,1
TLNE TXTPTR,760000 ;byte ptr now pointing to low order byte in word?
JRST DEP100 ;no. go deposit another "@"
IDIVI CNT,5 ;calculate negated number of ACs holding keyword
SUBI CNT,4
POPJ P,
;READ READY GETCH
READ: MOVE B,[POINT 7,TMPBUF];read in a line typed by the user
MOVEM B,LINEBP ;initialize byte ptr to beginning of line
READ1: INCHWL CHAR
CAIN CHAR,CR
JRST READ4
CAIN CHAR,LF
JRST READ3
CAIN CHAR,ALT
JRST READ2
IDPB CHAR,B ;save the char
TRNN CHAR,600 ;is it an activation char?
JRST READ1 ;no. get next char
READ2: OUTSTR CRLF ;echo a CRLF when user types ALT or char with
JRST READ5 ; control bits on
READ3: OUTCHR [CR] ;echo a CR when user types LF
JRST READ5
READ4: INCHWL C ;read the LF of a user-typed CRLF
READ5: MOVEM CHAR,BRCHAR ;save the activation character
SETZ CHAR, ;place a zero byte after text string
IDPB CHAR,B
POPJ P,
;read in answer to yes/no question
READY: PUSH P,CHAR ;save CHAR
PUSH P,BRCHAR ;and BRCHAR
PUSH P,B ;and B
MOVE B,[POINT 7,STORY]
PUSHJ P,READ1
POP P,B
POP P,BRCHAR ;restore 'em
POP P,CHAR
LDB A,[POINT 7,STORY,6]
CAIE A,"Y"
CAIN A,"y"
POPJ P, ;direct return if answer is Yes
AOS (P) ;skip return otherwise
CAIE A,"?"
AOS (P) ;double skip return unless "?"
POPJ P,
GETCH: ILDB CHAR,LINEBP ;subroutine to put into CHAR the next char from
GETCH1: CAIE CHAR," " ; the keyword expression that is not
CAIN CHAR,TAB ; a space or a tab.
JRST GETCH
POPJ P,
;GETAVL NUNAVL GTORIG
GETAVL: MOVE STYPTR,AVSLST ;get available word for story list
JUMPN STYPTR,.+2
NUNAVL: LGEERR {STORY LIST SPACE EXCEEDED! (TEMPORARY LISTS EXCEED 750 STORIES)} ; ;
MOVE A,(STYPTR) ;get ptr to 2nd available word and store it
MOVEM A,AVSLST ; in header of available list
HRRM STYPTR,(LIST3) ;link up last element to this new element
MOVE LIST3,STYPTR ;leave ptr to new element in LIST3
POPJ P,
GTORIG: HLRZ X2,INDEX+2(X) ;is this story a follow up of another?
JUMPN X2,GTORG2
MOVEI C,ORIGHD ;no. see if this story already on orig list
JRST GT0
GT1: HLRZ X1,(D) ;get index ptr of this list element
CAMN X,X1 ;is it the same story?
JRST CPOPJ1 ;yes. nothing to do but skip
MOVE C,D ;no. move down list
GT0: HRRZ D,(C) ;get ptr to next element in list
JUMPN D,GT1 ;are we at end of orig list
PUSHJ P,GETAVL ;yes. put this story at end of main list
HRLM X,(LIST3)
POPJ P,
GTORG2: MOVEI C,ORIGHD ;here we have the orig story of a follow up
JRST GTORG0 ; and we want to add story to orig list
GTORG1: HLRZ X1,(D) ;get index ptr of this list element
CAMN X2,X1 ;is this the same story?
JRST CPOPJ1 ;yes. dont have to do anything. skip return
MOVE C,D ;move down list
GTORG0: HRRZ D,(C) ;get ptr to next element in list
JUMPN D,GTORG1 ;are we at end of list?
GTORG4: EXCH C,LIST3 ;yes
PUSHJ P,GETAVL ;add this story at end of originals list
HRLZM X2,(LIST3)
MOVE LIST3,C ;restore LIST3
POPJ P,
;ADORIG RETLST
ADORIG: MOVEI C,ORIGHD# ;get ptr to head of list of original stories
JRST AD0
AD1: HLRZ X1,(D) ;get index ptr of this list element
MOVEI LIST3,SORDID(SORPTR) ;get ptr to header of main list
JRST AD2
AD3: HLRZ X,(B) ;get index ptr of this element
CAMN X,X1 ;is it same story?
JRST AD4 ;yes. nothing special to do
CAMG X,NEWX ;no. is X in top part of INDEX?
JRST AD5 ;yes
CAML X,X1 ;no (bottom part)
CAMG X1,NEWX
JRST INSX
JRST AD6
AD5: CAMG X,X1 ;(X in top part)
CAML X1,NEWX
JRST AD6
INSX: PUSHJ P,GETAVL ;insert X1 at this point in main list
HRLI X1,(B) ;make new list element point to next one
MOVSM X1,(LIST3)
JRST AD4
AD6: MOVE LIST3,B ;advance down main list
AD2: HRRZ B,(LIST3) ;get ptr to next element in main list
JUMPN B,AD3 ;at end of list?
JRST INSX ;yes. place X1 here
AD4: MOVE C,D
AD0: HRRZ D,(C) ;get ptr to next list element
JUMPN D,AD1 ;at end of list?
SKIPN A,ORIGHD
POPJ P,
; JRST RETLST ;return list to free storage
;RETLST returns a list to available list storage. call is done like:
;;; SKIPE A,<address of list header>
;;; PUSHJ P,RETLST
;The header of the list is NOT cleared.
RETLST: MOVE C,A ;put ptr to first element of ret'd list
EXCH C,AVSLST ; in header for avail list
RET1: HRRZ B,(A) ;next element in list
JUMPE B,RET2 ;at end of list?
HRRZ A,(B) ;no. next element in list
JUMPN A,RET1 ;at end of list?
MOVE A,B ;yes
RET2: HRRZM C,(A) ;link up ret'd list with old avail list
POPJ P,
;SETUPI SETUP NEXT1 NEXT2
SETUPI: HRLM SORPTR,(P)
PUSHJ P,GETCH
PUSHJ P,PRIMAR
JRST SET0
SETUP: HRLM SORPTR,(P)
PUSHJ P,GETCH
PUSHJ P,FACTOR
SET0: TLZ F,OP1FLG+OP2FLG
HLRZ A,(P)
caie sorptr,1(a)
outstr [asciz\SORPTR ≠ A+1 in SETUP\]
caie sorptr,1(a)
exit 1,
HRRE LIST1,SORDID(A)
HLLZS SORDID(A)
HRRE LIST2,SORDID(SORPTR)
move sorptr,a
MOVEI LIST3,SORDID(SORPTR)
JUMPLE LIST1,SET1
TLO F,OP1FLG
MOVEM LIST1,HEAD1
HLRZ X1,(LIST1)
JRST SET2
SET1: MOVN LIST1,LIST1
HRRZ X1,LINKS+1(LIST1)
SETZM HEAD1
SET2: JUMPLE LIST2,SET3
TLO F,OP2FLG
MOVEM LIST2,HEAD2
HLRZ X2,(LIST2)
POPJ P,
SET3: MOVN LIST2,LIST2
HRRZ X2,LINKS+1(LIST2)
SETZM HEAD2
POPJ P,
NEXT1: TLNE F,OP1FLG
JRST NEXT11
HLRZ LIST1,LINKS(LIST1)
HRRZ X1,LINKS+1(LIST1)
POPJ P,
NEXT11: HRRZ LIST1,(LIST1)
HLRZ X1,(LIST1)
POPJ P,
NEXT2: TLNE F,OP2FLG
JRST NEXT21
HLRZ LIST2,LINKS(LIST2)
HRRZ X2,LINKS+1(LIST2)
POPJ P,
NEXT21: HRRZ LIST2,(LIST2)
HLRZ X2,(LIST2)
POPJ P,
;SDIFF
SDIFF: PUSHJ P,SETUP ;this must be first instr in SDIFF (see LOOK)
SD0: JUMPE LIST1,FINISH
JUMPE LIST2,COPY1
CAME X1,X2
JRST SD4
PUSHJ P,NEXT1
PUSHJ P,NEXT2
JRST SD0
SD4: CAML X1,OLDX
JRST SDBOTT
CAMG X1,X2
JRST SD1
SD2: PUSHJ P,GETAVL
HRLM X1,(LIST3)
PUSHJ P,NEXT1
JRST SD0
SD1: CAML X2,OLDX
JRST SD2
SD3: PUSHJ P,NEXT2
JRST SD0
SDBOTT: CAML X2,OLDX
CAMG X1,X2
JRST SD3
JRST SD2
;UNION
UNION: PUSHJ P,SETUP
UN0: JUMPE LIST1,COPY2
JUMPE LIST2,COPY1
CAME X1,X2
JRST UN4
PUSHJ P,GETAVL
HRLM X1,(LIST3)
PUSHJ P,NEXT1
PUSHJ P,NEXT2
JRST UN0
UN4: CAML X1,OLDX
JRST UNBOTT
CAMG X1,X2
JRST UN1
UN2: PUSHJ P,GETAVL
HRLM X1,(LIST3)
PUSHJ P,NEXT1
JRST UN0
UN1: CAML X2,OLDX
JRST UN2
UN3: PUSHJ P,GETAVL
HRLM X2,(LIST3)
PUSHJ P,NEXT2
JRST UN0
UNBOTT: CAML X2,OLDX
CAMG X1,X2
JRST UN3
JRST UN2
;INTER
INTER: PUSHJ P,SETUPI ;this must be first instr in INTER (see LOOK)
INT0: JUMPE LIST1,FINISH
JUMPE LIST2,FINISH
CAME X1,X2
JRST INT4
PUSHJ P,GETAVL
HRLM X1,(LIST3)
PUSHJ P,NEXT1
PUSHJ P,NEXT2
JRST INT0
INT4: CAML X1,OLDX
JRST INBOTT
CAMG X1,X2
JRST INT1
INT2: PUSHJ P,NEXT1
JRST INT0
INT1: CAML X2,OLDX
JRST INT2
INT3: PUSHJ P,NEXT2
JRST INT0
INBOTT: CAML X2,OLDX
CAMG X1,X2
JRST INT3
JRST INT2
;COPY1 COPY2 FINISH
COPY1: JUMPE LIST1,FINISH
TLNE F,OP1FLG
JRST COP12
COP11: PUSHJ P,GETAVL
HRLM X1,(LIST3)
HLRZ LIST1,LINKS(LIST1)
HRRZ X1,LINKS+1(LIST1)
JUMPN LIST1,COP11
JRST FINISH
COP12: PUSHJ P,GETAVL
HRLM X1,(LIST3)
HRRZ LIST1,(LIST1)
HLRZ X1,(LIST1)
JUMPN LIST1,COP12
JRST FINISH
COPY2: JUMPE LIST2,FINISH
TLNE F,OP2FLG
JRST COP22
COP21: PUSHJ P,GETAVL
HRLM X2,(LIST3)
HLRZ LIST2,LINKS(LIST2)
HRRZ X2,LINKS+1(LIST2)
JUMPN LIST2,COP21
JRST FINISH
COP22: PUSHJ P,GETAVL
HRLM X2,(LIST3)
HRRZ LIST2,(LIST2)
HLRZ X2,(LIST2)
JUMPN LIST2,COP22
FINISH: HLLZS (LIST3) ;put null ptr on end of resultant list
SKIPE A,HEAD1 ;is first list null?
PUSHJ P,RETLST ;no. return it to free storage
SKIPE A,HEAD2 ;is second list null?
JRST RETLST ;no. return it to free storage
POPJ P,
;LATEST SEQNBR
;build up a list of the latest n stories, where n is a number typed in.
LATEST: PUSHJ P,INNBR ;read in nbr of stories to be found (CNT)
LAT1: MOVEI LIST3,SORDID(SORPTR);set up list ptr to header of list
JUMPN CNT,.+2
MEDERR (MISSING OR ZERO COUNT AFTER ".") ; ;
MOVEM CNT,SAVCNT#
MOVE X,NEWX ;get index of NEW area
LAT3: CAMN X,OLDX ;check if index has run into OLD
JRST LAT4 ;it has. no more stories can be retrieved
SUBI X,XSIZE ;get previous index entry
CAIGE X,SPECS
MOVEI X,XLEN-XSIZE
PUSHJ P,GTORIG ;put original for this story onto the list
SOSLE SAVCNT ;have enough stories been found?
JRST LAT3
SEQ2:LAT4:HLLZS (LIST3) ;yes. put null ptr at end of list
PUSHJ P,ADORIG ;add to the list any originals referenced
TLZE F,NOTIFY ;notification requested?
OUTSTR [ASCIZ/NOTIFICATION NOT POSSIBLE FOR EXPRESSIONS CONTAINING "." OR "#" CONSTRUCTS
/]
JRST GETCH1
;build up a list of the stories within a given range of sequence numbers
SEQNBR: PUSHJ P,INNBR ;read in the seq nbr (CNT)
MOVEM CNT,SEQBEG
CAIN CHAR,":" ;is this a range of seq nbrs?
PUSHJ P,INNBR ;yes. get seq nbr for end of range
JUMPN CNT,SEQ3 ;if the end nbr is 0 and the
SKIPE SEQBEG ; beginning nbr is not 0, then
MOVEI CNT,-1 ; ∞ is used for the end nbr
SEQ3: MOVEM CNT,SEQEND
SUB CNT,SEQBEG
MOVEM CNT,SAVCNT#
MOVEI LIST3,SORDID(SORPTR);set up list ptr to header of list
MOVE X,NEWX ;get index of NEW area
SEQ1: CAMN X,OLDX ;has the index run into OLD already?
JRST SEQ2 ;yes. that's all the stories there are
SUBI X,XSIZE ;no. get index of previous story
CAIGE X,SPECS
MOVEI X,XLEN-XSIZE
HRRZ A,INDEX+2(X) ;get seq nbr for this story
CAMGE A,SEQBEG
JRST SEQ5
SKIPL SAVCNT
CAMG A,SEQEND
JRST SEQ4
JRST SEQ1
SEQ5: JUMPGE CNT,SEQ1
CAMG A,SEQEND
SEQ4: PUSHJ P,GTORIG ;put original for this story onto the list
JRST SEQ1 ;dont care whether story was on list
JRST SEQ1 ;go look for more stories
;GETSTY INNBR RDNBR PTZERO PRNTNO NXTDG PTREST
GETSTY: CAIE CHAR,"*" ;does the user want to reference the oldest story?
JRST RDNBR ;no. read in a story number
MOVE CNT,NFOUND ;yes. get the number of the oldest story
JRST GETCH
INNBR: ILDB CHAR,LINEBP ;load 1st char of number
RDNBR: SETZ CNT, ;CNT will hold the value of the number
RDNBR1: CAIG CHAR,"9" ;is present char a digit?
CAIGE CHAR,"0"
JRST GETCH1 ;no. return
IMULI CNT,=10 ;yes. multiply previous sum by =10 and
ADDI CNT,-60(CHAR) ; add in current digit
ILDB CHAR,LINEBP ;load the next potential digit
JRST RDNBR1
PTZERO: CAIGE PART1,=10
OUTCHR ["0"] ;print a leading zero if number is less than ten
PRNTNO: MOVE B,[POINT 7,DIGITS]
PUSHJ P,NXTDG
SETZ PART1,
IDPB PART1,B
OUTSTR DIGITS
POPJ P,
NXTDG: IDIVI PART1,=10
PUSH P,PART2
SKIPE PART1
PUSHJ P,NXTDG
POP P,PART1
ADDI PART1,60
IDPB PART1,B
POPJ P,
;type out remaining part of input line following an error
PTREST: OUTSTR [ASCIZ/: /]
JRST REST2
REST1: OUTCHR CHAR
ILDB CHAR,LINEBP
REST2: JUMPN CHAR,REST1
OUTSTR CRLF
POPJ P,
;PUTDAT CLEARU
PUTDAT: OPEN 16,DSK17
UBIGERR 124 ; ;OPEN FAILED ON DSK
MOVE A,PPN
MOVEM A,USEF+3
ENTER 16,USEF ;ENTER new USE.DAT
JRST NOUSE
PUSHJ P,GETDAT
JRST NOUSE
SETZ D,
CALLI D,27 ;RUNTIM
SUBM D,LOCDAT+CPUTIM ;calculate and store amount of cpu time used lately
MOVE CNT,[2-ULEN,,1]
NXTU: MOVE A,LOCDAT(CNT)
ADDM A,TOTDAT(CNT) ;add local data to grand totals kept in USE.DAT
AOBJN CNT,NXTU
MOVEI A,-ULEN
HRLM A,UCMD
OUT 16,UCMD
JRST .+2
JRST NOOUT ;OUTPUT FAILED
RELEAS 16,
CLEARU: SETZM LOCDAT
MOVE A,[XWD LOCDAT,LOCDAT+1]
BLT A,LOCDAT+ULEN-1
MOVEM D,LOCDAT+CPUTIM ;save total cpu time since login
POPJ P,
NOOUT: SUBM D,LOCDAT+CPUTIM ;put back earlier total cpu time since login
NOUSE: RELEAS 16,3
POPJ P,
;GETDAT PTIME
;read in usage data file
GETDAT: OPEN 15,DSK17
UBIGERR 130 ; ;OPEN FAILED ON DSK
MOVE A,PPN
MOVEM A,USEF+3
LOOKUP 15,USEF
JRST GETXIT
HLRE A,USEF+3 ;get size of data file
CAMGE A,[-ULEN] ;is it bigger than array?
MOVEI A,-ULEN ;yes. only read in enough to fill array?
HRLM A,UCMD ;store amount to read in
SETZM TOTDAT
MOVE A,[TOTDAT,,TOTDAT+1]
BLT A,TOTDAT+ULEN-1
IN 15,UCMD
AOS (P) ;skip return for success
GETXIT: RELEAS 15,
POPJ P,
PTIME: IDIVI A,=1000 ;convert time to seconds
IDIVI A,=60 ;convert time to minutes
MOVE C,A+1 ;save seconds
IDIVI A,=60 ;convert time to hours
MOVE PART1,A
PUSHJ P,PTZERO ;print hours
OUTCHR [":"]
MOVE PART1,A+1
PUSHJ P,PTZERO ;print minutes
OUTCHR [":"]
MOVE PART1,C
JRST PTZERO ;print seconds and return
;PRINTU
PRINTU: PUSHJ P,GETDAT ;read in usage data file
POPJ P, ;couldn't read in file. give up
SETO A,
GETLIN A ;get tty line number
HRRZ A,A
CAIL A,27 ;is it a DD?
CAIL A,120
JRST PU1 ;nope
DPYSIZ 0000 ;yup. move pp to top of screen
MOVEI A,1
CALLI A,31 ;SLEEP
PTWR1W [0↔14120] ;[BRK]P. clear screen
PTWR1W [0↔10116] ;[ESC]N. normalize pp
PU1: OUTSTR [ASCIZ \
DATA SINCE \]
LDB A,[POINT 11,TOTDAT,23] ;get time data cleared
IDIVI A,=60
MOVE PART1,A
PUSHJ P,PTZERO ;print hour
MOVE PART1,A+1
PUSHJ P,PTZERO ;print minutes
OUTCHR [" "]
PUSHJ P,PDATE
OUTSTR CRLFS
MOVE C,[4-ULEN,,3]
TOPU: OUTSTR @MSGDAT(C)
MOVE PART1,TOTDAT(C)
PUSHJ P,PRNTNO
OUTSTR CRLF
AOBJN C,TOPU
OUTSTR [ASCIZ/
CPU TIME (HR:MIN:SEC).........../]
MOVE A,TOTDAT+CPUTIM
PUSHJ P,PTIME
OUTSTR [ASCIZ/
SEARCH TIME (HR:MIN:SEC).........../]
MOVE A,TOTDAT+SRCTIM
PUSHJ P,PTIME
OUTSTR CRLFS
POPJ P,
PDATE: LDB A,[POINT 12,TOTDAT,35] ;PRINT A DATE
IDIVI A,=31
MOVEI PART1,1(A+1)
PUSHJ P,PRNTNO ;print day of month
IDIVI A,=12
OUTCHR ["-"]
OUTSTR MONTHS(A+1) ;print month
OUTCHR ["-"]
MOVEI PART1,=64(A)
JRST PRNTNO ;print year
;ZEROUS
ZEROUS: OUTSTR [ASCIZ \CLEAR? \]
INCHRW A
CAIE A,"%"
POPJ P,
INCHRW A
CAIE A,"π"
POPJ P,
OPEN 16,DSK17
UBIGERR 140 ; ;OPEN FAILED ON DSK
HLLZS USEF+1
SETZM USEF+2
MOVE A,PPN
MOVEM A,USEF+3
ENTER 16,USEF
JRST [RELEAS 16,
OUTSTR [ASCIZ \ FAILED
\]
POPJ P,]
CALLI A,400072 ;DSKTIM. get time/date
MOVEM A,TOTDAT
SETZM TOTDAT+1
MOVE A,[XWD TOTDAT+1,TOTDAT+2]
BLT A,TOTDAT+ULEN-1
MOVEI A,-ULEN
HRLM A,UCMD
OUT 16,UCMD
JRST .+2
UBIGERR 144 ; ;OUT UUO FAILED FOR USE.DAT
RELEAS 16,
OUTSTR [ASCIZ \ DONE\]
POPJ P,
;SAVPPN
SAVPPN: OPEN 14,DSK17
UBIGERR 150 ; ;OPEN FAILED ON DSK
MOVE B,PPN
MOVEM B,USERSF+3
LOOKUP 14,USERSF
JRST XPPN
HLRE A,USERSF+3
MOVE B,PPN
MOVEM B,USERSF+3
ENTER 14,USERSF
JRST XPPN
MOVN A,A
LDB B,[POINT 7,A,35]
ASH A,-7
JUMPE B,WRT
USETI 14,1(A)
MOVN C,B
HRLM C,PCMD
IN 14,PCMD
JRST .+2
JRST XPPN
WRT: USETO 14,1(A)
LDB A,[POINT 6,USRPPN,23]
TRCE A,40
TRO A,100 ;convert PPN from SIXBIT to ASCII
DPB A,[POINT 7,USERS(B),6]
LDB A,[POINT 6,USRPPN,29]
TRCE A,40
TRO A,100
DPB A,[POINT 7,USERS(B),13]
LDB A,[POINT 6,USRPPN,35]
TRCE A,40
TRO A,100
DPB A,[POINT 7,USERS(B),20]
MOVEI A," " ;put a space after the PPN
DPB A,[POINT 14,USERS(B),34]
SETZM USERS+1(B)
MOVNI B,2(B)
HRLM B,PCMD
OUTPUT 14,PCMD
TRO F,PPNDUN
XPPN: RELEAS 14,
POPJ P,
;READIT
READIT: HRRZ DISPL,INDEX+1(X) ;get the story's displ from beginning of rec
MOVE SIZE,X ;calculate the index of the next story
ADDI SIZE,XSIZE
CAIL SIZE,XLEN
MOVEI SIZE,SPECS
MOVN SIZE,INDEX+1(SIZE) ;subtract the rec nbr and displ of next story from zero
ADD SIZE,INDEX+1(X) ; and add in the rec nbr and displ of the
JUMPL SIZE,ONWARD ; current story. this gets negated size of current story
DOWN: MOVN SIZE,INDEX+3 ;the current story is the bottom one in NEWS
JUMPE SIZE,CPOPJ ;zero means this is a fake story. NEWS has never wrapped around
ADD SIZE,INDEX+1(X) ;recalculate its size using ptr to bottom of file
ONWARD: ASH SIZE,-13 ;shift out the =11 low order zero bits of the size
ASH DISPL,-13 ;shift out the =11 low order zero bits of the displ
MOVNM SIZE,TOTSIZ# ;save the size of the story (positive size)
SUB SIZE,DISPL ;add in the displ to get the amt that has to be read in
HRLM SIZE,CMD ;store this amt (negated) in the input command
AGAIN1: OPEN 4,DSK17 ;LOOKUP the NEWS file for reading in the story
UBIGERR 154 ; ;OPEN FAILED ON DSK
MOVE A,PPN
MOVEM A,NEWSF+3 ;store ppn of [ap,sys] in lookup block
LOOKUP 4,NEWSF
JRST [RELEASE 4, ;NEWS file in use. wait and try the LOOKUP again
MOVEI A,1
CALL A,[SIXBIT /SLEEP/]
JRST AGAIN1]
HLRZ A,INDEX+1(X) ;get the record nbr for this story
USETI 4,(A) ;select that record for input from NEWS
IN 4,CMD ;read in the story in STORY area
JRST .+2
UBIGERR 160 ; ;IN UUO FAILED TO READ IN NEWS STORY
RELEAS 4,
ADDI DISPL,STORY ;make DISPL into ptr to first word of the story
LDB B,[POINT 7,(DISPL),6] ;CALCULATE APPARENT SEQ NBR OF STORY READ
SUBI B,60 ; IN FROM NEWS
IMULI B,=10
LDB C,[POINT 7,(DISPL),13]
ADDI B,-60(C)
IMULI B,=10
LDB C,[POINT 7,(DISPL),20]
ADDI B,-60(C)
HRRZ A,INDEX+2(X) ;GET SEQ NBR FROM INDEX FOR THIS STORY
CAMN A,B ;CHECK CALCULATED SEQ NBR AGAINST THAT IN INDEX
CPOPJ1: AOS (P)
CPOPJ: POPJ P,
;SEARCH
CH←←0
BP←←1
J←←2
TEST←←3
SAVACS: BLOCK 20 ;block for storing AC during search in ACs
SEARCH: PUSHJ P,READIT
JRST SRCXIT ;story has disappeared, so keyword not found
AOS NBRSRC ;count number of stories searched
SETZM FNDIT#
MOVEM 17,SAVACS+17
MOVE 17,[XWD 0,SAVACS]
BLT 17,SAVACS+16 ;save the ACs
MOVE BP,DISPL
HRLI BP,440700 ;set up byte pointer into story
MOVE 17,[XWD CODE,4]
BLT 17,17 ;move loop code into ACs
JRST NX ;jump into loop
CODE:
PHASE 4 ;this code will go into ACs 4 to 17
NX←←. ILDB CH,BP
CAIE CH,
CAIN CH,
JRST GOT1
NX1←←. JUMPN CH,NX
JRST EOS ;found end of story without finding keyword
NX2←←. ILDB CH,BP ;CH holds char from story
ANDI CH,137 ;make upper case
ILDB TEST,TESTB# ;TEST holds char from keyword
CAIN CH,(TEST)
NX3←←. SOJGE J,NX2
JRST GOTALL
DEPHASE
GOT1: SETZM END#
MOVE J,MINBP
MOVEM J,TESTB
MOVE J,NEND
JRST NX3
GOTALL: JUMPGE J,NOHIT
SKIPE END
JRST HIT
SETOM END
MOVEM BP,SAVBP#
ILDB CH,BP ;get char after last char in possible keyword
CAIL CH,"A" ;is it a word delimiter?
JRST NOHIT ;no. it's a letter
CAIGE CH,"0"
JRST .+3
CAIG CH,"9"
JRST NOHIT ;no. it's a digit
SUB BP,WDIF
SKIPA J,BDIF
IBP BP
SOJGE J,.-1
LDB CH,BP ;get char before first char in possible keyword
CAIL CH,"A" ;is it a word delimiter?
JRST NOHIT ;no. it's a letter
CAIGE CH,"0"
JRST .+3
CAIG CH,"9"
JRST NOHIT ;no. it's a digit
MOVE J,FSTBP
MOVEM J,TESTB
MOVE J,NBEG
JRST NX3
NOHIT: SKIPE END
JRST NOHIT1
LDB CH,BP
JRST NX1
NOHIT1: MOVE BP,SAVBP
JRST NX
HIT: SETOM FNDIT
EOS: MOVE 17,[XWD SAVACS,0]
BLT 17,17
SKIPN FNDIT
JRST SRCXIT
PUSHJ P,GTORIG ;found keyword in story, so link up original for
OUTCHR ["*"] ; this story
MOVE D,SAVACS+D ;GTORIG wipes out D
SRCXIT: SKIPE INTFG
JRST SRCHX1
INCHSL GARBLE# ;if user has typed a line, he wants to end search
POPJ P, ;has not typed a line. continue
CLRBFI ;clear the interrupting char(s) from tty buffer
SRCHX1: OUTSTR [ASCIZ/ Search terminated manually after /]
EXCH X,NBRSRC ;print number of stories searched
PUSHJ P,PRNTNO
MOVE X,NBRSRC ;restore X
OUTSTR [ASCIZ/ stories./]
AOS (P) ;skip return from SEARCH when interrupted
POPJ P,
;LOOK
F0: DEC 132,138,95,31,35,40,35,63,38,64
FA: DEC 1814,346,773,871,2597,456,402,760,1761,43,116,818,644
DEC 1746,1753,551,10,1459,1347,1897,548,294,292,88,313,17
LOOK0: OUTSTR CRLF
LOOK: AOS USCH ;bump counter of number of searches
SETZM INTFG
OUTSTR [ASCIZ/Searching.../]
SETZ A,
CALLI A,27 ;RUNTIM
MOVEM A,STTIM# ;save the cpu time to calculate search time
MOVEI A,-1
MOVEM A,MINFRQ# ;initialize min freq to large nbr
MOVE A,FSTBP#
SETO CNT, ;count nbr of chars - 1
LOOK3: ILDB C,A ;find least common char and convert
JUMPE C,LOOK4 ; all letters to upper case
ANDI C,137 ; by turning off 40 bit
DPB C,A
CAIGE C,"0"-40
AOJA CNT,LOOK3 ;neither a digit or a letter (must be space)
MOVE D,FA-101(C) ;get freq assuming letter
TRNN C,100
MOVE D,F0-20(C) ;get freq for digit
CAML D,MINFRQ ;less freq than any so far?
AOJA CNT,LOOK3 ;no
ADDI CNT,1
MOVEM D,MINFRQ# ;yes. save freq,
MOVEM A,MINBP# ; byte ptr,
MOVEM CNT,NBEG# ; nbr of chars before this,
MOVNM CNT,NEND# ; and negative of nbr of char before.
JRST LOOK3
IDPB C,A ;fill out word in POLISH with zero bytes
LOOK4: TLNE A,760000
JRST .-2
TLZ A,-1
SKIPN (A)
SUBI A,1
SUBI A,POLISH
MOVE C,POLPTR
SUB A,C
HRRZM A,POLISH(C) ;save length of search string in POLISH
HRLM A,POLISH(C) ;put length in both left and right halves
ADDB A,POLPTR ;adjust POLPTR to last word in string
CAIL A,POLLEN
HALT . ; ;
ADDM CNT,NEND#
LDB C,MINBP
ORI C,40
HRRM C,CODE+1
ANDI C,137
HRRM C,CODE+2
ADDI CNT,2
IDIVI CNT,5
JUMPE CNT+1,LOOK5
ADDI CNT,1
MOVN CNT+1,CNT+1
ADDI CNT+1,5
LOOK5: MOVEM CNT,WDIF#
MOVEM CNT+1,BDIF#
SETZM NBRSRC# ;zero out the number of stories searched
MOVEI LIST3,SORDID(SORPTR)
MOVE A,P
JRST LOOK7
LOOK6: HRRZ B,(A)
CAIE B,SDIFF+1 ;is this the second part of a set diff?
CAIN B,INTER+1 ;no. second part of an intersection?
JRST GOTINT ;yes to one of these
SUB A,[1,,1]
LOOK7: CAME A,[IOWD PDLEN,PDLIST] ;have we searched entire stack?
JRST LOOK6 ;nope
MOVE X,NEWX
LOOK1: CAMN X,OLDX ;have we searched the oldest story yet?
JRST LOOK2 ;yes. finish up
SUBI X,XSIZE ;no. get index of next older story
CAIGE X,SPECS
MOVEI X,XLEN-XSIZE
PUSHJ P,SEARCH ;search the story for the keyword
JRST LOOK1
LOOK2: HLLZS (LIST3) ;put null ptr on end of list
PUSHJ P,ADORIG ;add to list any originals referenced
OUTSTR CRLF
SETZ X,
CALLI X,27
SUB X,STTIM ;calculate search time and print it
ADDM X,LOCDAT+SRCTIM ;add to previous search time
OUTSTR [ASCIZ/Search time in msec: /]
PUSHJ P,PRNTNO
OUTSTR CRLF
JRST GETCH1
GOTINT: HLRZ D,(A) ;get ptr to story list for first part of expr
HRRE D,SORDID(D) ;get ptr to first story in list
JUMPGE D,GOTIN1 ;ptr < 0 means ptr into LINKS
MOVN D,D
JRST .+2
GOTIN2: HLRZ D,LINKS(D) ;get ptr to next element in list
JUMPE D,LOOK2 ;zero ptr means end of list
HRRZ X,LINKS+1(D) ;get index ptr for this story in list
PUSHJ P,SEARCH
JRST GOTIN2
JRST LOOK2
GOTIN3: HRRZ D,(D) ;get ptr to next element in list
GOTIN1: JUMPE D,LOOK2
HLRZ X,(D) ;get index ptr for this story
PUSHJ P,SEARCH
JRST GOTIN3
JRST LOOK2 ;search was interrupted
;SHRINK UUCODE
SHRINK: HLRZ A,JOBSA
MOVEM A,JOBFF
CALLI A,11 ;CORE UUO to release extra core accumulated
UBIGERR 164 ; ;CORE UUO FAILED
POPJ P,
UUCODE: 0
HLRZ A,40 ;get type of error
ANDI A,777000 ;zero out AC field
; OUTCHR ["?"]
CAIN A,(<UBIGERR>) ;is it a super horrendous error?
JRST BADERR
OUTSTR @40
LDB B,[POINT 4,40,12]; pick up AC field of error UUO
JUMPE B,.+2
CLRBFI ;clear input buffer if AC field is non-zero
TRZ F,AUTOCN
CAIN A,(<UERR3>)
JRST RESET
PUSHJ P,PTREST
CAIN A,(<UERR2>)
JRST RSTART
CAIN A,(<UERR1>)
JRST APE1
BADERR: OUTSTR [ASCIZ/
SUPER HORRENDOUS ERROR #/]
HRRZ PART1,40 ;get error number
PUSHJ P,PRNTNO
CALLI 0
CALLI 12
;TELLKY TELLSL TELLSC
TELLKY: OUTSTR INFO1
PUSHJ P,READ
PUSHJ P,GETCH
CAIN CHAR,"?"
OUTSTR INFO2
JRST APE1
TELLSL: OUTSTR INFO3
PUSHJ P,READ
PUSHJ P,GETCH
CAIN CHAR,"?"
OUTSTR INFO4
JRST ASKER1
TELLSC: OUTSTR INFO5
TRZ F,AUTOSC
JRST ASKSRC
INFO1: ASCIZ %
DETAILED INFORMATION ON THIS PROGRAM IS IN THE FILE: APE.ME[UP,DOC]
WAR represents all stories mentioning WAR.
WAR*PEACE represents all stories mentioning both WAR and PEACE.
WAR+PEACE represents all stories mentioning either WAR or PEACE.
WAR-PEACE represents all stories mentioning WAR but not PEACE.
.n (n an unsigned integer) represents the latest n stories.
#n represents all stories with AP sequence number n.
#n:m represents all stories with AP numbers from n to m.
@<filenm> means read expressions from the command file <filenm>.
@!<filenm>means automatically read from the command file <filenm>.
@ means read another expression from the command file
(opens the file APE.CMD if no command file open).
@! means automatically read expressions from the command file
(opens the file APE.CMD if no command file open).
NOW type ? and RETURN to get MORE HELP, else type just RETURN.%
comment %
$<expr> requests notification when a story comes in matching the
keyword expression <expr>.
$ means type out all notification requests and then allow
deleting any or all of them.%
INFO2: ASCIZ %
Each keyword represents a group of stories, namely all the stories
it occurs in. A keyword expression consists of either a single
keyword or an expression built from keywords and the operators
* (for INTERSECTION), + (for UNION), and - (for SET DIFFERENCE).
These operators have their usual precedences (* evaluated first).
Note that + and - are BINARY operators only. Parentheses can be
used freely in keyword expressions.
The special forms ".n" (latest n stories), "#n" (stories numbered n),
and "#n:m" (stories numbered from n to m) can appear anywhere in
place of a keyword.
For a list of the keywords, read the file WORDS.SRT[AP,SYS]. To have
your own special keywords added to the list, SEND a note to ME.%
INFO3: ASCIZ %
Syntax for the selection line is as follows, where [...] denotes
an optional quantity and ...|... denotes exclusive alternatives:
(The order is irrelevant except that any filename must come first.)
[<filenm>[/Q|/X]←] [<story selection>] [S] [K] [W] [C|F|L|D]
<filenm> means save stories in given file (no extension or PPN allowed).
/Q means replace file if it already exists.
/X means extend file if it already exists.
The syntax for <story selection> is:
[ N | [=]<nbr>[:<nbr>] ]
where <nbr> is a positive or negative integer (k represents the k newest
stories and -k represents the k oldest stories) and
= means reverse the order of the stories and
N means select None of the stories.
S means Spool the selected stories (not allowed with F or L options).
K means Kill automatic reading from command file.
W means type out the keyWords each story is categorized by.
C means allow Choosing which stories get typed out completely.
F means type out only the First few lines of each story.
L means type out only the Last few lines of each story.
D means Dont type out the stories at all (useful if filing or spooling).
NOW type ? and RETURN to get MORE HELP, else type just RETURN.%
INFO4: ASCIZ %
If you use the Choose feature, the first few lines of each story will
be typed out and then you will be expected to indicate whether you want
to read the rest of the story. If you do not want to read the rest of
the story, type just carriage return. To read the rest of the story,
type altmode, linefeed, or any character (except "I") followed by
carriage return. If you don't want to read any more of the stories,
type "I" and carriage return. You will be allowed to quit reading a
story at the beginning of each part (take, correction, etc.).
In the <story selection>:
To select the k newest stories in normal order, type the number "k".
To select the k oldest stories in normal order, type the number "-k".
To select the jth story thru the kth story, type "j:k". Note that
in this construction, "1" represents the newest story, larger
numbers represent older stories, "*" represents the oldest story,
and finally, "-k" represents the kth oldest story. Thus, "-1" is
equivalent to "*"; both represent the oldest story. The stories
will come out in the order you specify: story j first, story k
last.
For even more help, read the file APE.ME[UP,DOC].
%
INFO5: ASCIZ %
A search of the news file is available for words that are not in the
keyword dictionary. Multiple word keyword searches are also possible
but occurrences that are split between lines will not be found. It
takes about 8 to 10 secs of computer time PER unknown keyword to
search the whole news file. However, if an unknown keyword occurs
as the SECOND part of an intersection or difference (eg, NIXON * JJJJ
or NIXON - JJJJ), then only the necessary stories are searched (in
the examples, only those stories containing NIXON).
During a search for a keyword, each time a story is found that
contains the keyword, an asterisk (*) is typed out. You may inter-
rupt the search at any time by typing [ESC] I or carriage return.
Any stories found up to that point will be available. Stories are
searched in the order of newest to oldest. To get a search, answer
the question below with a Y and carriage return; type ? and return
to get this summary and just carriage return to avoid a search.
%
;NOTE
NOTE: PUSHJ P,NOTPPN ;is this guy allowed to make notif requests?
POPJ P, ;NO!
SETOM RQBUF ;first two words of a request are -1
SETOM RQBUF+1
CALLI A,14 ;DATE
ADDI A,2*=31 ;let request live two months
HRL A,B ;NOTPPN left programmer name in B.
MOVSM A,RQBUF+3 ;save date,,programmer name in request
AOS A,POLPTR ;get number of words for polish expression
HRL A,A ;and save it for request
MOVEM A,RQBUF+2 ;also prepare to save total length of request
MOVEI B,3 ; including 7 special words less first 4
ADDM B,RQBUF+2
MOVE B,[POLISH,,RQBUF+4] ;BLT polish expression into output buffer
BLT B,RQBUF+3(A)
SETZM RQBUF+4(A) ;first word after polish is a zero
MOVE B,[POINT 7,TMPBUF]
ILDB C,B
CAIE C,"$" ;replace the $ with a (
JRST .-2
MOVEI C,"("
DPB C,B
MOVE B,LINEBP ;(LINEBP now points at zero byte after keyw expr)
MOVEI C,")" ;add a ) after keyw expr
DPB C,B
TDZA C,C
IDPB C,B ;deposit zero bytes until end of word
TLNE B,760000
JRST .-2
MOVEI B,1-TMPBUF(B) ;compute length of keyw expr
ADDB B,RQBUF+2 ;and include in total length of request
ADDI A,RQBUF+5 ;prepare to blt keyword expression into
HRLI A,TMPBUF ; the request output buffer
BLT A,RQBUF+1(B)
MOVEI A,-1
MOVEM A,RQBUF+2(B) ;next to last word of request is 0,,-1
SETZM A,RQBUF+3(B) ;last word of request is 0
MOVNI B,4(B)
HRLM B,NCMD ;put length of request in output command
LOCK: MOVEI A,10 ;number of times we will try to interlock
MOVEM A,TIMER# ; the notification data file(s)
LOCK1: OPEN 10,DSK17
UBIGERR 170 ; ;
MOVSI A,'TMP' ;NOTIF.TMP is ENTERed to set the lock
MOVEM A,NOTIFF+1
MOVE A,PPN
MOVEM A,NOTIFF+3
ENTER 10,NOTIFF
JRST LOKOUT ;lock already was set by someone else
NOTE2: OPEN 11,DSK17 ;it's all ours!
UBIGERR 174 ; ;
MOVSI A,'ADD' ;request goes into NOTIF.ADD
MOVEM A,NOTIFF+1
MOVE A,PPN
MOVEM A,NOTIFF+3
LOOKUP 11,NOTIFF ;see if NOTIF.ADD already exists
JRST NOLOOK
NOTE3: MOVE A,PPN
MOVEM A,NOTIFF+3
ENTER 11,NOTIFF
JRST NOENTR
UGETF 11,B ;extend NOTIF.ADD if in RA mode (if LOOKUP succeeded)
OUT 11,NCMD ;write out request onto file
RELEAS 11, ;close request file
RELEAS 10,3 ;CLEAR LOCK!
AOS UNOTIF
OUTSTR [ASCIZ/Notification request accepted.
/]
POPJ P,
LOKOUT: MOVEI A,1 ;ENTER failed. lock already set
CALLI A,31 ;SLEEP
SOSL TIMER#
JRST LOCK1
OUTSTR [ASCIZ/Sorry -- Notification data file in use. Type Y to try again./]
PUSHJ P,READY
JRST LOCK ;"Y"
JRST .-3 ;"?"
OUTSTR [ASCIZ/Notification request rejected.
/] ;any other char
RELEAS 10,3
POPJ P,
NOLOOK: HRRZ B,NOTIFF+1 ;LOOKUP failed.
JUMPE B,NOTE3 ;is it because the file does not exist?
CAIE B,3 ;NO!!!!
UBIGERR 200 ; ;
UBIGERR 204 ; ;
NOENTR: HRRZ B,NOTIFF+1 ;ENTER failed on NOTIF.ADD
CAIE B,3 ;is it because the file is busy?
UBIGERR 210 ; ;NO!!!
RELEAS 11, ;yes. make it not quite so busy
MOVEI A,1
CALLI A,31 ;SLEEP
SOSL TIMER
JRST NOTE2 ;try the ENTER again
RELEAS 10,3 ;timed out. give up. UNLOCK!!
OUTSTR [ASCIZ/LOCKED OUT OF NOTIFICATION DATA FILE!
/]
POPJ P,
NOTPPN: HRRZ B,USRPPN ;see if this guy is allowed to make requests
CAIE B,'GUE' ;too many different GUEs
CAIN B,'SYS' ;same for SYSs
JRST NOTNOT
CAIE B,'FOO'
CAIN B,'100'
JRST NOTNOT
AOS (P) ;skip return on guy ok
POPJ P,
NOTNOT: MOVE A,[POINT 6,B,17]
OUTSTR [ASCIZ/Sorry -- '/]
NOTNT2: ILDB C,A
ADDI C,40
OUTCHR C ;type out his programmer name
TLNE A,770000
JRST NOTNT2
OUTSTR [ASCIZ/' cannot make notification requests.
/]
POPJ P,
;NOTEDP
NOTEDL: TLOA F,DELB ;DISPLAY AND ALLOW DELETION
NOTEDP: TLZ F,DELB ;JUST DISPLAY REQUESTS
AOS UNDSPY
TRZ F,TMPB!TMPB2!TMPB3 ;access first file, no requests found yet
MOVE A,USRPPN
CAMN A,PPN
TRO F,TMPB3
INIT 10,10
SIXBIT /DSK/
MBUF
UBIGERR 214 ; ;INIT FAILED ON DSK
SETZM NOTIFF+1 ;start with main file: NOTIF
RQLOOK: MOVE A,PPN
MOVEM A,NOTIFF+3
LOOKUP 10,NOTIFF
JRST [HRRZ B,NOTIFF+1 ;get LOOKUP error code
JUMPE B,RQEOF ;if no file, pretend eof
TRNN F,TMPB ;is this NOTIF.ADD?
JRST RQEOF ;no. give up on this file
SOSG TIMER ;have we tried enough times?
JRST TIMOUT ;YES
MOVEI B,1 ;NO. Wait and try again
SLEEP B,
JRST RQLOOK]
NXRQRC: PUSHJ P,GNTF1 ;get the first word of the next record of the file
AOJN A,RQEOF ;if the first word is not -1, assume eof
NXRQ: PUSHJ P,GNTF ;pick up serial number of rq
MOVEM A,SERIAL# ; and save it
PUSHJ P,GNTF ;pick up length word: P,,L
HRRZ B,A ; and save the length L of the remainder of rq
CAIL B,5 ;make sure length not too small
CAIL B,200 ; and not too big
UBIGERR 220 ; ;LENGTH OF RQ OUT OF BOUNDS
PUSHJ P,GNTF ;pick up DATE,,PN
HRRZ D,USRPPN
TRNN F,TMPB3
CAIN D,(A)
JRST SHOWRQ ;SHOW THIS REQUEST TO THIS GUY and let him delete it
PUSHJ P,GNTF
SOJG B,.-1 ;SKIP TO 0 AT END OF REQUEST
JUMPN A,RQEOF ;if not 0, something is wrong. pretend eof
NXRQ1: PUSHJ P,GNTF ;get first word of next request. should be -1
AOJE A,NXRQ ;if it isn't -1, pretend eof
RQEOF: TROE F,TMPB ;did we just finish the last file?
JRST RQEND ;yes. we are done
NTCHG: CLOSE 10, ;no.
MOVSI A,'CHG' ;see if NOTIF.CHG exists
MOVEM A,NOTIFF+1
MOVE A,PPN
MOVEM A,NOTIFF+3
LOOKUP 10,NOTIFF
JRST NTADD
OUTSTR [ASCIZ\
There are a few new requests that I can't access right now.
\]
NTADD: CLOSE 10,
MOVEI A,10 ;this is the max number of times we will try to
MOVEM A,TIMER ; do a LOOKUP on NOTIF.ADD
MOVSI A,'ADD'
MOVEM A,NOTIFF+1
JRST RQLOOK
TIMOUT: OUTSTR [ASCIZ\
DATA FILE BUSY. Type Y to try again.\]
PUSHJ P,READY ;read in user's response
JRST NTADD ;"Y"
JRST TIMOUT ;"?"
RQEND: RELEAS 10,
TRNN F,TMPB2
OUTSTR [ASCIZ\
No notification requests found.
\]
JRST RSTART
SHOWRQ: TRON F,TMPB2
OUTSTR [ASCIZ\
PN Expiration Expression
\]
HLRZM A,TOTDAT ;save expiration date for printing
PUSHJ P,SIXOUT ;type out programmer name of requestor
OUTCHR [TAB]
PUSHJ P,PDATE ;print expiration date
OUTCHR [TAB]
MOVE B,[IOWD 200,TMPBUF];put asciz expression into TMPBUF for outstr'ing
PUSHJ P,GNTF
JUMPN A,.-1 ;skip to zero word following polish expr
PUSHJ P,GNTF
PUSH B,A ;deposit a word of the asciz string into TMPBUF buf
TLNE A,-1 ;end of asciz string?
JRST .-3 ;no. get next word
OUTSTR TMPBUF
PUSHJ P,GNTF ;get last word of request
JUMPE A,.+2 ; which should be zero
OUTSTR [ASCIZ\ *** GARBAGED ***\]
TLNE F,DELB ;is he being allowed to delete requests?
JRST SHWRQ2 ;YES
OUTSTR CRLF ;NO
JRST GOEND
SHWRQ2: OUTSTR [ASCIZ\ Delete?\]
PUSHJ P,READY ;read answer
JRST DELRQ ;"Y"
JRST [OUTSTR [ASCIZ \Do you want to delete the above request?\]
JRST .-2] ;"?"--try again
CAIN A,";"
TLZ F,DELB ;";" means dont ask me about deleting requests
GOEND: TRNE F,TMPB ;which file are we working on?
JRST NXRQRC ;NOTIF.ADD
JRST NXRQ1 ;NOTIF
DELRQ: TRNE F,TMPB
JRST DLADD ;this request to be deleted is in NOTIF.ADD
DLMAIN: SETOM RQBUF ;this request to be deleted is in NOTIF
MOVE A,SERIAL#
HRROM A,RQBUF+1
MOVEI A,2
MOVEM A,RQBUF+2
SETZM RQBUF+3
MOVEI A,-1
MOVEM A,RQBUF+4
SETZM RQBUF+5
MOVEI A,-6
HRLM A,NCMD
PUSHJ P,LOCK ;interlock data file and write delete request
JRST GOEND ;move to end of input request
DLADD: ;open NOTIF.ADD in RA mode and zero out the request
JRST NXRQRC ;go read next record/request
comment ⊗ a sample type-out:
(NIXON*WAR) expires 4 Mar 73. Delete? end of comment ⊗
GNTF: SOSG MBUF+2
GNTF1: IN 10,
JRST [ILDB A,MBUF+1
POPJ P,]
SETZ A,
POPJ P,
SIXOUT: MOVE B,[POINT 6,A,17]
SIX1: ILDB C,B
JUMPE C,.+3
ADDI C,40
OUTCHR C
TLNE B,770000
JRST SIX1
POPJ P,
;TYKEYS
TYKEYS: AOS UKEYS
MOVE D,[POINT 7,STORY]
HLRZ A,INDEX(X)
JUMPE A,[OUTSTR [ASCIZ/No Keywords
/]
JRST FINKEY]
TYKE1: MOVE B,A
HRRE B,LINKS(B)
JUMPG B,.-1
MOVN B,B
PUSHJ P,GETFAT
MOVEI C,CR
IDPB C,D
MOVEI C,LF
IDPB C,D
HLRZ A,LINKS+1(A)
JUMPN A,TYKE1
SETZ C,
IDPB C,D
OUTSTR STORY
FINKEY: TLNN F,DONT
OUTSTR [ASCIZ/- - - - - - - - - -/]
OUTSTR CRLF
POPJ P,
GETFAT: HLLZ C,DICT(B)
HLLM C,(P)
GETFA4: HLRZ C,DICT+2(B)
CAML C,DICLEN
JRST GETFA2
HRRZ SIZE,DICT+2(C)
CAME B,SIZE
JRST GETFA3
MOVE B,C
JRST GETFA4
GETFA3: HLRZ SIZE,DICT+1(C)
CAME B,SIZE
JRST GETFA2
MOVE B,C
PUSHJ P,GETFAT
GETFA2: HLRZ B,(P)
ADD B,[440700,,WORDS]
GETFA5: ILDB C,B
CAIN C,"@"
JRST GETFA6
IDPB C,D
JRST GETFA5
GETFA6: MOVEI C," "
IDPB C,D
POPJ P,
;READFL RFAUTO RFCON
TVLEAD: ASCIZ /COMMENT ⊗ VALID /]
CFILE: BLOCK 4
SCFILE: SIXBIT /APE/
SIXBIT /CMD/
BLOCK 2
CBUF: BLOCK 3
READFL: PUSHJ P,GETCH
TRZ F,AUTOCN
CAIE CHAR,"!"
JRST RF00
TRO F,AUTOCN
PUSHJ P,GETCH
RF00: JUMPN CHAR,OPENFL ;is there a file name?
TRNE F,INFILE ;no. is there an old file open?
JRST RFAUTO ;yes
TRZ F,CON
INIT 12,
SIXBIT /DSK/
CBUF
UBIGERR 224 ; ;CANT INIT THE DSK
SETZM SCFILE+3 ;read standard command file from user's area
LOOKUP 12,SCFILE
JRST RFERR5
OUTSTR [ASCIZ/[OPENING APE.CMD]/]
JRST RF11
RF01: PUSHJ P,RF5 ;read until semicolon
POPJ P, ;some error
TRNN F,INFILE ;hit eof yet?
POPJ P, ;yes
RFAUTO: TRNE F,CON ;no. did last expr end with a comma?
JRST RF01 ;yes
JRST RFCON ;no. get next expr
OPENFL: SETZM CFILE ;read in new file name and
SETZM CFILE+1 ; LOOKUP the new file
SETZM CFILE+3
MOVE B,[POINT 6,CFILE] ;byte ptr to deposit file name in LOOKUP bk
MOVEI C,6 ;max length of file name
PUSHJ P,RFNAM1 ;read in file name
JRST RF1 ;CR found
JRST RFEXT ;"."
JRST RFPPN ;"["
JRST RFERR2 ;","
RFEXT: MOVE B,[POINT 6,CFILE+1] ;byte ptr to deposit file name ext
MOVEI C,3 ;max length of ext
PUSHJ P,RFNAME ;read in file name ext
JRST RF1 ;CR found
JRST RFERR2 ;"."
JRST RFPPN ;"["
JRST RFERR2 ;","
RFPPN: MOVE B,[POINT 6,D] ;byte ptr to deposit project code
MOVEI C,3 ;max length of project
PUSHJ P,RFNAME ;read in project code
JRST RF6 ;CR found. use given project and disk PN
JRST RFERR2 ;"."
JRST RFERR2 ;"["
JRST RF7 ;","
LSH D,-6 ;right justify project in left half of D
RF6: SOJGE C,.-1
SETZ C,
DSKPPN C,
HRR D,C ;GET PROGRAMMER NAME FROM DSKPPN
MOVEM D,CFILE+3 ;store PPN
JRST RF1
LSH D,-6 ;right justify project in left half of D
RF7: SOJGE C,.-1
EXCH D,CFILE+3 ;store project and clear D
MOVE B,[POINT 6,D,17] ;byte ptr to deposit programmer name
MOVEI C,3 ;max length of programmer name
PUSHJ P,RFNAME ;read in programmer name
JRST RF0 ;CR found (or "]")
JRST RFERR2 ;"."
JRST RFERR2 ;"["
JRST RFERR2 ;","
RF0: JRST .+2
LSH D,-6
SOJGE C,.-1
HRRM D,CFILE+3 ;store programmer name
RF1: TRZ INFILE!CON
INIT 12,0
SIXBIT /DSK/
CBUF
UBIGERR 230 ; ;INIT FAILED ON DSK
SKIPN CFILE ;zero file name means use APE.CMD
SKIPE CFILE+1 ;must also have zero extension
JRST RF12
MOVSI A,'APE'
MOVEM A,CFILE
MOVSI A,'CMD'
MOVEM A,CFILE+1
RF12: LOOKUP 12,CFILE
JRST RFERR3
RF11: IN 12,
JRST .+2
JRST RFERR4
AOS UATFL
MOVE C,[POINT 7,TVLEAD] ;see if the file is in TV format
MOVE D,CBUF+1
RF2: ILDB A,C
JUMPE A,RFTV
ILDB B,D ;look at first few chars of file
CAMN A,B
JRST RF2
AOS CBUF+2
JRST RFCON ;not a TV file
RFTV: IN 12, ;find first record after TV directory page
JRST .+2
JRST RFERR4
ILDB CHAR,CBUF+1
CAIE CHAR,FF
JRST RFTV
RFCON: OUTCHR ["@"]
TROA F,TYPEFL
RF5: TRZ F,TYPEFL
TRO F,INFILE+AUTOSC
MOVE B,[POINT 7,TMPBUF]
MOVEM B,LINEBP
RF3: SOSG CBUF+2 ;buffer used up?
IN 12, ;yes. get another
JRST RF4
RELEAS 12, ;eof (assume so anyway)
PUSHJ P,SHRINK
TRZ F,INFILE!AUTOCN!CON
JRST ENDFIL
RF4: ILDB CHAR,CBUF+1 ;get char from buffer
MOVE A,@CBUF+1 ;get whole word to test for SOS line number
TRNE A,1 ;is this an SOS line number?
JRST [MOVNI A,6 ;yes. advance byte pointer and byte
ADDM A,CBUF+2 ; count to first char after the
AOS CBUF+1 ; tab that follows line number
ILDB CHAR,CBUF+1
JRST .+1]
JUMPE CHAR,RF3 ;ignore nulls,
CAIE CHAR,CR ;carriage returns,
CAIN CHAR,LF ;line feeds,
JRST RF3
CAIN CHAR,FF ;and form feeds.
JRST RF3
CAIN CHAR,"," ;break on comma
JRST CONXPR
CAIN CHAR,";" ; or semicolon.
JRST ENDXPR
IDPB CHAR,B ;accept any other characters
JRST RF3 ;get next char from file
CONXPR: TROA F,CON ;note that command line continues (comma)
ENDXPR: TRZ F,CON ;note that command line ended (semicolon)
ENDFIL: SETZ CHAR,
IDPB CHAR,B ;place null byte at end of line
TRNE F,TYPEFL
OUTSTR TMPBUF ;type out the line from the file
TRNN F,INFILE ;have we hit eof?
OUTSTR [ASCIZ/[EOF]/] ;yes. tell the poor guy
TRNE F,TYPEFL
OUTSTR CRLF
MOVEI A,CR
MOVEM A,BRCHAR ;pretend command line ended with CR
AOS (P) ;success return
POPJ P, ;done at last!
;RFERR1-5 RFNAME
RFERR1: SUB P,[1,,1]
RFERR2: OUTSTR [ASCIZ/ILLEGAL FILE SPECIFICATION/]
JRST PTREST
RFERR3: OUTSTR [ASCIZ/CANT FIND COMMAND FILE
/]
POPJ P,
RFERR4: OUTSTR [ASCIZ/COMMAND FILE INPUT ERROR
/]
POPJ P,
RFERR5: OUTSTR [ASCIZ/NO COMMAND FILE OPEN
CANT FIND APE.CMD
/]
POPJ P,
RFNAME: PUSHJ P,GETCH
RFNAM1: JUMPE CHAR,CPOPJ ;end of file name specification?
CAIN CHAR,"." ;no. beginning of extension?
JRST CPOPJ1 ;yes. skip return
CAIN CHAR,"[" ;no. beginning of ppn?
JRST CPOPJ2 ;yes. double skip return
CAIN CHAR,"," ;no. end of project
JRST CPOPJ3 ;yes. triple skip return
CAIN CHAR,"]" ;no. end of ppn
POPJ P, ;yes. direct return
SOJL C,RFERR1 ;no. file name specification too long?
TRZ CHAR,40 ;no. convert char to sixbit
TRZE CHAR,100
TRO CHAR,40
IDPB CHAR,B ;save this sixbit char
JRST RFNAME
CPOPJ3: AOS (P)
CPOPJ2: AOS (P)
JRST CPOPJ1
PATCH: BLOCK 20 ;PATCH AREA
END APE